aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--coregrind/core.h22
-rw-r--r--coregrind/linux/core_os.c2
-rw-r--r--coregrind/m_aspacemgr/aspacemgr.c28
-rw-r--r--coregrind/m_libcbase.c50
-rw-r--r--coregrind/m_libcfile.c188
-rw-r--r--coregrind/m_scheduler/scheduler.c10
-rw-r--r--coregrind/m_signals.c66
-rw-r--r--coregrind/m_syscalls/Makefile.am8
-rw-r--r--coregrind/m_syscalls/README_SYSCALLS.txt15
-rw-r--r--coregrind/m_syscalls/priv_syscalls-generic.h324
-rw-r--r--coregrind/m_syscalls/priv_syscalls-linux.h116
-rw-r--r--coregrind/m_syscalls/priv_syscalls-main.h43
-rw-r--r--coregrind/m_syscalls/priv_syscalls-x86-linux.h17
-rw-r--r--coregrind/m_syscalls/priv_syscalls.h515
-rw-r--r--coregrind/m_syscalls/priv_types_n_macros.h348
-rw-r--r--coregrind/m_syscalls/syscall-x86-linux.S110
-rw-r--r--coregrind/m_syscalls/syscalls-amd64-linux.c4
-rw-r--r--coregrind/m_syscalls/syscalls-generic.c (renamed from coregrind/m_syscalls/syscalls.c)3773
-rw-r--r--coregrind/m_syscalls/syscalls-linux.c1279
-rw-r--r--coregrind/m_syscalls/syscalls-main.c970
-rw-r--r--coregrind/m_syscalls/syscalls-x86-linux.c1837
-rw-r--r--coregrind/m_tooliface.c2
-rw-r--r--coregrind/pub_core_libcbase.h68
-rw-r--r--coregrind/pub_core_scheduler.h4
-rw-r--r--coregrind/pub_core_signals.h19
-rw-r--r--coregrind/pub_core_syscalls.h24
-rw-r--r--coregrind/pub_core_tooliface.h2
-rw-r--r--coregrind/vg_mylibc.c271
-rw-r--r--include/basic_types.h11
-rw-r--r--include/pub_tool_tooliface.h2
30 files changed, 5578 insertions, 4550 deletions
diff --git a/coregrind/core.h b/coregrind/core.h
index a371342df..6b668209f 100644
--- a/coregrind/core.h
+++ b/coregrind/core.h
@@ -105,7 +105,7 @@ extern Int VG_(poll)( struct vki_pollfd *, UInt nfds, Int timeout);
/* system/mman.h */
extern void* VG_(mmap) ( void* start, SizeT length, UInt prot, UInt flags,
UInt sf_flags, UInt fd, OffT offset );
-extern void* VG_(mmap_native)( void* start, SizeT length, UInt prot, UInt flags,
+extern SysRes VG_(mmap_native)( void* start, SizeT length, UInt prot, UInt flags,
UInt fd, OffT offset );
extern Int VG_(munmap) ( void* start, SizeT length );
extern Int VG_(mprotect) ( void *start, SizeT length, UInt prot );
@@ -120,6 +120,16 @@ extern void VG_(env_remove_valgrind_env_stuff) ( Char** env );
extern void VG_(nanosleep)(struct vki_timespec *);
+/* Simple Valgrind-internal atfork mechanism */
+/* Internal atfork handlers */
+typedef void (*vg_atfork_t)(ThreadId);
+extern void VG_(atfork)(vg_atfork_t pre, vg_atfork_t parent,
+ vg_atfork_t child);
+extern void VG_(do_atfork_pre) (ThreadId tid);
+extern void VG_(do_atfork_parent)(ThreadId tid);
+extern void VG_(do_atfork_child) (ThreadId tid);
+
+
/* ---------------------------------------------------------------------
Exports of vg_syscall.S
------------------------------------------------------------------ */
@@ -129,16 +139,6 @@ extern void VG_(nanosleep)(struct vki_timespec *);
// cause problems when passing 32-bit integers on 64-bit platforms, because
// the top 32-bits might not be zeroed appropriately, eg. as would happen
// with the 6th arg on AMD64 which is passed on the stack.
-extern Word VG_(do_syscall) ( UInt, UWord, UWord, UWord, UWord, UWord, UWord );
-
-// Macros make life easier.
-#define vgPlain_do_syscall0(s) VG_(do_syscall)((s),0,0,0,0,0,0)
-#define vgPlain_do_syscall1(s,a) VG_(do_syscall)((s),(a),0,0,0,0,0)
-#define vgPlain_do_syscall2(s,a,b) VG_(do_syscall)((s),(a),(b),0,0,0,0)
-#define vgPlain_do_syscall3(s,a,b,c) VG_(do_syscall)((s),(a),(b),(c),0,0,0)
-#define vgPlain_do_syscall4(s,a,b,c,d) VG_(do_syscall)((s),(a),(b),(c),(d),0,0)
-#define vgPlain_do_syscall5(s,a,b,c,d,e) VG_(do_syscall)((s),(a),(b),(c),(d),(e),0)
-#define vgPlain_do_syscall6(s,a,b,c,d,e,f) VG_(do_syscall)((s),(a),(b),(c),(d),(e),(f))
extern void VG_(sigreturn)(void);
diff --git a/coregrind/linux/core_os.c b/coregrind/linux/core_os.c
index dc1241033..18bf8c2bb 100644
--- a/coregrind/linux/core_os.c
+++ b/coregrind/linux/core_os.c
@@ -29,6 +29,7 @@
*/
#include "core.h"
+#include "pub_core_libcbase.h"
#include "pub_core_debuglog.h"
#include "pub_core_libcassert.h"
#include "pub_core_libcprint.h"
@@ -140,6 +141,7 @@ void VGA_(reap_threads)(ThreadId self)
while (!i_am_the_only_thread()) {
/* Let other thread(s) run */
VG_(vg_yield)();
+ VG_(poll_signals)(self);
}
vg_assert(i_am_the_only_thread());
}
diff --git a/coregrind/m_aspacemgr/aspacemgr.c b/coregrind/m_aspacemgr/aspacemgr.c
index 4eb20e242..343a4cb91 100644
--- a/coregrind/m_aspacemgr/aspacemgr.c
+++ b/coregrind/m_aspacemgr/aspacemgr.c
@@ -590,7 +590,7 @@ void VG_(unmap_range)(Addr addr, SizeT len)
len = VG_PGROUNDUP(len);
if (debug)
- VG_(printf)("unmap_range(%p, %lu)\n", addr, len);
+ VG_(printf)("unmap_range(%p, %llu)\n", addr, (ULong)len);
if (0) show_segments("unmap_range(BEFORE)");
end = addr+len;
@@ -698,6 +698,8 @@ VG_(map_file_segment)( Addr addr, SizeT len,
static const Bool debug = False || mem_debug;
Segment* s;
Int idx;
+ HChar* stage2_suffix = "lib/valgrind/stage2";
+ Bool is_stage2 = VG_(strstr)(filename, stage2_suffix) != NULL;
if (debug)
VG_(printf)(
@@ -707,6 +709,8 @@ VG_(map_file_segment)( Addr addr, SizeT len,
" filename='%s')\n",
addr, (ULong)len, prot, flags, dev, ino, off, filename);
+ if (0) show_segments("before map_file_segment");
+
/* Everything must be page-aligned */
vg_assert(VG_IS_PAGE_ALIGNED(addr));
len = VG_PGROUNDUP(len);
@@ -741,7 +745,9 @@ VG_(map_file_segment)( Addr addr, SizeT len,
file, then try reading symbols from it.
*/
if (s->seginfo == NULL
- && (addr+len < VG_(valgrind_base) || addr > VG_(valgrind_last))
+ && ( (addr+len < VG_(valgrind_base) || addr > VG_(valgrind_last))
+ || is_stage2
+ )
&& (flags & (SF_MMAP|SF_NOSYMS)) == SF_MMAP) {
if (off == 0
&& s->fnIdx != -1
@@ -855,8 +861,8 @@ Addr VG_(find_map_space)(Addr addr, SizeT len, Bool for_client)
if (debug) {
VG_(printf)("\n\n");
- VG_(printf)("find_map_space(%p, %lu, %d) ...\n",
- addr, len, for_client);
+ VG_(printf)("find_map_space(%p, %llu, %d) ...\n",
+ addr, (ULong)len, for_client);
}
if (0) show_segments("find_map_space: start");
@@ -957,8 +963,8 @@ Addr VG_(find_map_space)(Addr addr, SizeT len, Bool for_client)
ret = 0; /* not found */
if (debug)
- VG_(printf)("find_map_space(%p, %lu, %d) -> %p\n\n",
- addr, len, for_client, ret);
+ VG_(printf)("find_map_space(%p, %llu, %d) -> %p\n\n",
+ addr, (ULong)len, for_client, ret);
if (fixed) {
vg_assert(ret == 0 || ret == addrOrig);
@@ -982,7 +988,7 @@ Addr VG_(find_map_space)(Addr addr, SizeT len, Bool for_client)
void VG_(pad_address_space)(Addr start)
{
Addr addr = (start == 0) ? VG_(client_base) : start;
- void* ret;
+ SysRes ret;
Int i = 0;
Segment* s = i >= segments_used ? NULL : &segments[i];
@@ -1010,7 +1016,7 @@ void VG_(pad_address_space)(Addr start)
void VG_(unpad_address_space)(Addr start)
{
Addr addr = (start == 0) ? VG_(client_base) : start;
- Int ret;
+ SysRes ret;
Int i = 0;
Segment* s = i >= segments_used ? NULL : &segments[i];
@@ -1539,11 +1545,11 @@ Bool VGA_(setup_pointercheck)(Addr client_base, Addr client_end)
0, // ! seg not present
1, // useable
};
- int ret = VG_(do_syscall3)(__NR_modify_ldt, 1, (UWord)&ldt, sizeof(ldt));
- if (ret < 0) {
+ SysRes ret = VG_(do_syscall3)(__NR_modify_ldt, 1, (UWord)&ldt, sizeof(ldt));
+ if (ret.isError) {
VG_(message)(Vg_UserMsg,
"Warning: ignoring --pointercheck=yes, "
- "because modify_ldt failed (errno=%d)", -ret);
+ "because modify_ldt failed (errno=%d)", ret.val);
return False;
} else {
return True;
diff --git a/coregrind/m_libcbase.c b/coregrind/m_libcbase.c
index 1ab10d37d..2ed7f8216 100644
--- a/coregrind/m_libcbase.c
+++ b/coregrind/m_libcbase.c
@@ -471,6 +471,56 @@ void VG_(ssort)( void* base, SizeT nmemb, SizeT size,
#undef SORT
}
+/* ---------------------------------------------------------------------
+ A function for doing syscalls.
+ ------------------------------------------------------------------ */
+
+#if defined(VGP_x86_linux)
+extern UInt do_syscall_x86_linux_WRK (
+ UInt syscall_no,
+ UInt a1, UInt a2, UInt a3,
+ UInt a4, UInt a5, UInt a6
+ );
+asm(
+"do_syscall_x86_linux_WRK:\n"
+" push %esi\n"
+" push %edi\n"
+" push %ebx\n"
+" push %ebp\n"
+" movl 16+ 4(%esp),%eax\n"
+" movl 16+ 8(%esp),%ebx\n"
+" movl 16+12(%esp),%ecx\n"
+" movl 16+16(%esp),%edx\n"
+" movl 16+20(%esp),%esi\n"
+" movl 16+24(%esp),%edi\n"
+" movl 16+28(%esp),%ebp\n"
+" int $0x80\n"
+" popl %ebp\n"
+" popl %ebx\n"
+" popl %edi\n"
+" popl %esi\n"
+" ret\n"
+);
+#endif
+
+
+SysRes VG_(do_syscall) ( UWord sysno, UWord a1, UWord a2, UWord a3,
+ UWord a4, UWord a5, UWord a6 )
+{
+ SysRes res;
+
+# if defined(VGP_x86_linux)
+ UInt eax = do_syscall_x86_linux_WRK(sysno,a1,a2,a3,a4,a5,a6);
+ res = VG_(mk_SysRes_x86_linux)( eax );
+# else
+
+# error VG_(do_syscall): unimplemented on this platform
+
+# endif
+
+ return res;
+}
+
/*--------------------------------------------------------------------*/
/*--- end ---*/
/*--------------------------------------------------------------------*/
diff --git a/coregrind/m_libcfile.c b/coregrind/m_libcfile.c
index 974dcdbdb..34ca5798d 100644
--- a/coregrind/m_libcfile.c
+++ b/coregrind/m_libcfile.c
@@ -33,7 +33,6 @@
#include "pub_core_libcassert.h"
#include "pub_core_libcfile.h"
#include "pub_core_options.h"
-#include "pub_core_syscalls.h" // For VG_(is_kerror)()
#include "vki_unistd.h"
/* ---------------------------------------------------------------------
@@ -67,86 +66,77 @@ Int VG_(safe_fd)(Int oldfd)
/* Returns -1 on failure. */
Int VG_(open) ( const Char* pathname, Int flags, Int mode )
{
- Int fd = VG_(do_syscall3)(__NR_open, (UWord)pathname, flags, mode);
- return fd;
+ SysRes res = VG_(do_syscall3)(__NR_open, (UWord)pathname, flags, mode);
+ return res.isError ? -1 : res.val;
}
void VG_(close) ( Int fd )
{
- VG_(do_syscall1)(__NR_close, fd);
+ (void)VG_(do_syscall1)(__NR_close, fd);
}
Int VG_(read) ( Int fd, void* buf, Int count)
{
- Int res;
- res = VG_(do_syscall3)(__NR_read, fd, (UWord)buf, count);
- return res;
+ SysRes res = VG_(do_syscall3)(__NR_read, fd, (UWord)buf, count);
+ return res.isError ? -1 : res.val;
}
Int VG_(write) ( Int fd, const void* buf, Int count)
{
- Int res;
- res = VG_(do_syscall3)(__NR_write, fd, (UWord)buf, count);
- return res;
+ SysRes res = VG_(do_syscall3)(__NR_write, fd, (UWord)buf, count);
+ return res.isError ? -1 : res.val;
}
Int VG_(pipe) ( Int fd[2] )
{
- Int ret = VG_(do_syscall1)(__NR_pipe, (UWord)fd);
- return VG_(is_kerror)(ret) ? -1 : 0;
+ SysRes res = VG_(do_syscall1)(__NR_pipe, (UWord)fd);
+ return res.isError ? -1 : 0;
}
OffT VG_(lseek) ( Int fd, OffT offset, Int whence)
{
- Int res;
- res = VG_(do_syscall3)(__NR_lseek, fd, offset, whence);
- if (VG_(is_kerror)(res)) res = -1;
- return res;
+ SysRes res = VG_(do_syscall3)(__NR_lseek, fd, offset, whence);
+ return res.isError ? (-1) : 0;
}
Int VG_(stat) ( Char* file_name, struct vki_stat* buf )
{
- Int res;
- res = VG_(do_syscall2)(__NR_stat, (UWord)file_name, (UWord)buf);
- return res; /* return -ve error */
+ SysRes res = VG_(do_syscall2)(__NR_stat, (UWord)file_name, (UWord)buf);
+ return res.isError ? (-1) : 0;
}
Int VG_(fstat) ( Int fd, struct vki_stat* buf )
{
- Int res;
- res = VG_(do_syscall2)(__NR_fstat, fd, (UWord)buf);
- return VG_(is_kerror)(res) ? (-1) : 0;
+ SysRes res = VG_(do_syscall2)(__NR_fstat, fd, (UWord)buf);
+ return res.isError ? (-1) : 0;
}
Int VG_(dup2) ( Int oldfd, Int newfd )
{
- Int res;
- res = VG_(do_syscall2)(__NR_dup2, oldfd, newfd);
- return VG_(is_kerror)(res) ? (-1) : res;
+ SysRes res = VG_(do_syscall2)(__NR_dup2, oldfd, newfd);
+ return res.isError ? (-1) : res.val;
}
Int VG_(rename) ( Char* old_name, Char* new_name )
{
- Int res;
- res = VG_(do_syscall2)(__NR_rename, (UWord)old_name, (UWord)new_name);
- return VG_(is_kerror)(res) ? (-1) : 0;
+ SysRes res = VG_(do_syscall2)(__NR_rename, (UWord)old_name, (UWord)new_name);
+ return res.isError ? (-1) : 0;
}
Int VG_(unlink) ( Char* file_name )
{
- Int res;
- res = VG_(do_syscall1)(__NR_unlink, (UWord)file_name);
- return VG_(is_kerror)(res) ? (-1) : 0;
+ SysRes res = VG_(do_syscall1)(__NR_unlink, (UWord)file_name);
+ return res.isError ? (-1) : 0;
}
/* Nb: we do not allow the Linux extension which malloc()s memory for the
buffer if buf==NULL, because we don't want Linux calling malloc() */
Char* VG_(getcwd) ( Char* buf, SizeT size )
{
- Word res;
+ SysRes res;
vg_assert(buf != NULL);
res = VG_(do_syscall2)(__NR_getcwd, (UWord)buf, size);
- return VG_(is_kerror)(res) ? ((Char*)NULL) : (Char*)res;
+ return res.isError ? ((Char*)NULL) : (Char*)res.val;
}
/* Alternative version that does allocate the memory. Easier to use. */
@@ -170,20 +160,18 @@ Bool VG_(getcwd_alloc) ( Char** out )
Int VG_(readlink) (Char* path, Char* buf, UInt bufsiz)
{
- Int res;
+ SysRes res;
/* res = readlink( path, buf, bufsiz ); */
res = VG_(do_syscall3)(__NR_readlink, (UWord)path, (UWord)buf, bufsiz);
- if (VG_(is_kerror)(res)) res = -1;
- return res;
+ return res.isError ? -1 : res.val;
}
Int VG_(getdents) (UInt fd, struct vki_dirent *dirp, UInt count)
{
- Int res;
+ SysRes res;
/* res = getdents( fd, dirp, count ); */
res = VG_(do_syscall3)(__NR_getdents, fd, (UWord)dirp, count);
- if (VG_(is_kerror)(res)) res = -1;
- return res;
+ return res.isError ? -1 : res.val;
}
/* ---------------------------------------------------------------------
@@ -309,133 +297,119 @@ Int parse_inet_addr_and_port ( UChar* str, UInt* ip_addr, UShort* port )
# undef GET_CH
}
-
static
Int my_socket ( Int domain, Int type, Int protocol )
{
-// AMD64/Linux doesn't define __NR_socketcall... see comment above
-// VG_(sigpending)() for more details.
-#ifdef __amd64__
- I_die_here;
-#else
- Int res;
- UWord args[3];
+# if defined(VGP_x86_linux)
+ SysRes res;
+ UWord args[3];
args[0] = domain;
args[1] = type;
args[2] = protocol;
res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_SOCKET, (UWord)&args);
- if (VG_(is_kerror)(res))
- res = -1;
- return res;
-#endif
+ return res.isError ? -1 : res.val;
+# else
+ // AMD64/Linux doesn't define __NR_socketcall... see comment above
+ // VG_(sigpending)() for more details.
+ I_die_here;
+# endif
}
static
Int my_connect ( Int sockfd, struct vki_sockaddr_in* serv_addr,
Int addrlen )
{
-// AMD64/Linux doesn't define __NR_socketcall... see comment above
-// VG_(sigpending)() for more details.
-#ifdef __amd64__
- I_die_here;
-#else
- Int res;
- UWord args[3];
+# if defined(VGP_x86_linux)
+ SysRes res;
+ UWord args[3];
args[0] = sockfd;
args[1] = (UWord)serv_addr;
args[2] = addrlen;
res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_CONNECT, (UWord)&args);
- if (VG_(is_kerror)(res))
- res = -1;
- return res;
-#endif
+ return res.isError ? -1 : res.val;
+# else
+ // AMD64/Linux doesn't define __NR_socketcall... see comment above
+ // VG_(sigpending)() for more details.
+ I_die_here;
+# endif
}
Int VG_(write_socket)( Int sd, void *msg, Int count )
{
-// AMD64/Linux doesn't define __NR_socketcall... see comment above
-// VG_(sigpending)() for more details.
-#ifdef __amd64__
- I_die_here;
-#else
/* This is actually send(). */
-
/* Requests not to send SIGPIPE on errors on stream oriented
sockets when the other end breaks the connection. The EPIPE
error is still returned. */
Int flags = VKI_MSG_NOSIGNAL;
- Int res;
- UWord args[4];
+# if defined(VGP_x86_linux)
+ SysRes res;
+ UWord args[4];
args[0] = sd;
args[1] = (UWord)msg;
args[2] = count;
args[3] = flags;
res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_SEND, (UWord)&args);
- if (VG_(is_kerror)(res))
- res = -1;
- return res;
-#endif
+ return res.isError ? -1 : res.val;
+# else
+ // AMD64/Linux doesn't define __NR_socketcall... see comment above
+ // VG_(sigpending)() for more details.
+ I_die_here;
+# endif
}
Int VG_(getsockname) ( Int sd, struct vki_sockaddr *name, Int *namelen)
{
-// AMD64/Linux doesn't define __NR_socketcall... see comment above
-// VG_(sigpending)() for more details.
-#ifdef __amd64__
- I_die_here;
-#else
- Int res;
- UWord args[3];
+# if defined(VGP_x86_linux)
+ SysRes res;
+ UWord args[3];
args[0] = sd;
args[1] = (UWord)name;
args[2] = (UWord)namelen;
res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_GETSOCKNAME, (UWord)&args);
- if(VG_(is_kerror)(res))
- res = -1;
- return res;
-#endif
+ return res.isError ? -1 : res.val;
+# else
+ // AMD64/Linux doesn't define __NR_socketcall... see comment above
+ // VG_(sigpending)() for more details.
+ I_die_here;
+# endif
}
Int VG_(getpeername) ( Int sd, struct vki_sockaddr *name, Int *namelen)
{
-// AMD64/Linux doesn't define __NR_socketcall... see comment above
-// VG_(sigpending)() for more details.
-#ifdef __amd64__
- I_die_here;
-#else
- Int res;
- UWord args[3];
+# if defined(VGP_x86_linux)
+ SysRes res;
+ UWord args[3];
args[0] = sd;
args[1] = (UWord)name;
args[2] = (UWord)namelen;
res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_GETPEERNAME, (UWord)&args);
- if(VG_(is_kerror)(res))
- res = -1;
- return res;
-#endif
+ return res.isError ? -1 : res.val;
+# else
+ // AMD64/Linux doesn't define __NR_socketcall... see comment above
+ // VG_(sigpending)() for more details.
+ I_die_here;
+# endif
}
Int VG_(getsockopt) ( Int sd, Int level, Int optname, void *optval,
Int *optlen)
{
-// AMD64/Linux doesn't define __NR_socketcall... see comment above
-// VG_(sigpending)() for more details.
-#ifdef __amd64__
- I_die_here;
-#else
- Int res;
- UWord args[5];
+# if defined(VGP_x86_linux)
+ SysRes res;
+ UWord args[5];
args[0] = sd;
args[1] = level;
args[2] = optname;
args[3] = (UWord)optval;
args[4] = (UWord)optlen;
res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_GETSOCKOPT, (UWord)&args);
- if(VG_(is_kerror)(res))
- res = -1;
- return res;
-#endif
+ return res.isError ? -1 : res.val;
+# else
+ I_die_here;
+ // AMD64/Linux doesn't define __NR_socketcall... see comment above
+ // VG_(sigpending)() for more details.
+# endif
}
diff --git a/coregrind/m_scheduler/scheduler.c b/coregrind/m_scheduler/scheduler.c
index 9be79d5aa..64e297c09 100644
--- a/coregrind/m_scheduler/scheduler.c
+++ b/coregrind/m_scheduler/scheduler.c
@@ -338,7 +338,8 @@ void VG_(set_sleeping)(ThreadId tid, ThreadStatus sleepstate)
if (VG_(clo_trace_sched)) {
Char buf[50];
- VG_(sprintf)(buf, "now sleeping in state %s", name_of_thread_state(sleepstate));
+ VG_(sprintf)(buf, "now sleeping in state %s",
+ name_of_thread_state(sleepstate));
print_sched_event(tid, buf);
}
}
@@ -410,8 +411,6 @@ void VG_(vg_yield)(void)
VG_(nanosleep)(&ts);
VG_(set_running)(tid);
-
- VG_(poll_signals)(tid); /* something might have happened */
}
@@ -566,8 +565,6 @@ void mostly_clear_thread_record ( ThreadId tid )
until the caller is finally done with the thread stack. */
VG_(threads)[tid].status = VgTs_Zombie;
- VG_(threads)[tid].syscallno = -1;
-
VG_(sigemptyset)(&VG_(threads)[tid].sig_mask);
VG_(sigemptyset)(&VG_(threads)[tid].tmp_sig_mask);
@@ -613,6 +610,7 @@ static void sched_fork_cleanup(ThreadId me)
if (tid != me) {
mostly_clear_thread_record(tid);
VG_(threads)[tid].status = VgTs_Empty;
+ VG_(clear_syscallInfo)(tid);
}
}
@@ -908,6 +906,8 @@ void VG_(nuke_all_threads_except) ( ThreadId me, VgSchedReturnCode src )
"VG_(nuke_all_threads_except): nuking tid %d\n", tid);
VG_(threads)[tid].exitreason = src;
+ if (src == VgSrc_FatalSig)
+ VG_(threads)[tid].os_state.fatalsig = VKI_SIGKILL;
VG_(kill_thread)(tid);
}
}
diff --git a/coregrind/m_signals.c b/coregrind/m_signals.c
index e126ec920..5f3adc5b4 100644
--- a/coregrind/m_signals.c
+++ b/coregrind/m_signals.c
@@ -124,7 +124,9 @@ typedef struct SigQueue {
# define VGP_UCONTEXT_STACK_PTR(uc) ((uc)->uc_mcontext.esp)
# define VGP_UCONTEXT_FRAME_PTR(uc) ((uc)->uc_mcontext.ebp)
# define VGP_UCONTEXT_SYSCALL_NUM(uc) ((uc)->uc_mcontext.eax)
-# define VGP_UCONTEXT_SYSCALL_RET(uc) ((uc)->uc_mcontext.eax)
+# define VGP_UCONTEXT_SYSCALL_SYSRES(uc) \
+ /* Convert the value in uc_mcontext.eax into a SysRes. */ \
+ VG_(mk_SysRes_x86_linux)( (uc)->uc_mcontext.eax )
#elif defined(VGP_amd64_linux)
# define VGP_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_mcontext.rip)
# define VGP_UCONTEXT_STACK_PTR(uc) ((uc)->uc_mcontext.rsp)
@@ -327,10 +329,11 @@ void calculate_SKSS_from_SCSS ( SKSS* dst )
/* SA_ONESHOT: ignore client setting */
- /* SA_RESTART: ignore client setting and always set it for us
- (even though we never rely on the kernel to restart a
+ /* SA_RESTART: ignore client setting and always set it for us.
+ Though we never rely on the kernel to restart a
syscall, we observe whether it wanted to restart the syscall
- or not, which helps VGA_(interrupted_syscall)()) */
+ or not, which is needed by
+ VG_(fixup_guest_state_after_syscall_interrupted) */
skss_flags |= VKI_SA_RESTART;
/* SA_NOMASK: ignore it */
@@ -458,7 +461,7 @@ static Int sas_ss_flags ( ThreadId tid, Addr m_SP )
}
-Int VG_(do_sys_sigaltstack) ( ThreadId tid, vki_stack_t* ss, vki_stack_t* oss )
+SysRes VG_(do_sys_sigaltstack) ( ThreadId tid, vki_stack_t* ss, vki_stack_t* oss )
{
Addr m_SP;
@@ -479,18 +482,18 @@ Int VG_(do_sys_sigaltstack) ( ThreadId tid, vki_stack_t* ss, vki_stack_t* oss )
if (ss != NULL) {
if (on_sig_stack(tid, STACK_PTR(VG_(threads)[tid].arch))) {
- return -VKI_EPERM;
+ return VG_(mk_SysRes_Error)( VKI_EPERM );
}
if (ss->ss_flags != VKI_SS_DISABLE
&& ss->ss_flags != VKI_SS_ONSTACK
&& ss->ss_flags != 0) {
- return -VKI_EINVAL;
+ return VG_(mk_SysRes_Error)( VKI_EINVAL );
}
if (ss->ss_flags == VKI_SS_DISABLE) {
VG_(threads)[tid].altstack.ss_flags = VKI_SS_DISABLE;
} else {
if (ss->ss_size < VKI_MINSIGSTKSZ) {
- return -VKI_ENOMEM;
+ return VG_(mk_SysRes_Error)( VKI_ENOMEM );
}
VG_(threads)[tid].altstack.ss_sp = ss->ss_sp;
@@ -498,13 +501,13 @@ Int VG_(do_sys_sigaltstack) ( ThreadId tid, vki_stack_t* ss, vki_stack_t* oss )
VG_(threads)[tid].altstack.ss_flags = 0;
}
}
- return 0;
+ return VG_(mk_SysRes_Success)( 0 );
}
-Int VG_(do_sys_sigaction) ( Int signo,
- const struct vki_sigaction *new_act,
- struct vki_sigaction *old_act )
+SysRes VG_(do_sys_sigaction) ( Int signo,
+ const struct vki_sigaction *new_act,
+ struct vki_sigaction *old_act )
{
if (VG_(clo_trace_signals))
VG_(message)(Vg_DebugExtraMsg,
@@ -523,7 +526,8 @@ Int VG_(do_sys_sigaction) ( Int signo,
/* don't let them use our signals */
if ( (signo > VKI_SIGVGRTUSERMAX)
&& new_act
- && !(new_act->ksa_handler == VKI_SIG_DFL || new_act->ksa_handler == VKI_SIG_IGN) )
+ && !(new_act->ksa_handler == VKI_SIG_DFL
+ || new_act->ksa_handler == VKI_SIG_IGN) )
goto bad_signo_reserved;
/* Reject attempts to set a handler (or set ignore) for SIGKILL. */
@@ -556,7 +560,7 @@ Int VG_(do_sys_sigaction) ( Int signo,
if (new_act) {
handle_SCSS_change( False /* lazy update */ );
}
- return 0;
+ return VG_(mk_SysRes_Success)( 0 );
bad_signo:
if (VG_(needs).core_errors && VG_(clo_verbosity) >= 1
@@ -565,7 +569,7 @@ Int VG_(do_sys_sigaction) ( Int signo,
"Warning: bad signal number %d in sigaction()",
signo);
}
- return -VKI_EINVAL;
+ return VG_(mk_SysRes_Error)( VKI_EINVAL );
bad_signo_reserved:
if (VG_(needs).core_errors && VG_(clo_verbosity) >= 1
@@ -577,7 +581,7 @@ Int VG_(do_sys_sigaction) ( Int signo,
" the %s signal is used internally by Valgrind",
signame(signo));
}
- return -VKI_EINVAL;
+ return VG_(mk_SysRes_Error)( VKI_EINVAL );
bad_sigkill_or_sigstop:
if (VG_(needs).core_errors && VG_(clo_verbosity) >= 1
@@ -589,7 +593,7 @@ Int VG_(do_sys_sigaction) ( Int signo,
" the %s signal is uncatchable",
signame(signo));
}
- return -VKI_EINVAL;
+ return VG_(mk_SysRes_Error)( VKI_EINVAL );
}
@@ -655,10 +659,10 @@ void do_setmask ( ThreadId tid,
}
-int VG_(do_sys_sigprocmask) ( ThreadId tid,
- Int how,
- vki_sigset_t* set,
- vki_sigset_t* oldset )
+SysRes VG_(do_sys_sigprocmask) ( ThreadId tid,
+ Int how,
+ vki_sigset_t* set,
+ vki_sigset_t* oldset )
{
switch(how) {
case VKI_SIG_BLOCK:
@@ -666,13 +670,12 @@ int VG_(do_sys_sigprocmask) ( ThreadId tid,
case VKI_SIG_SETMASK:
vg_assert(VG_(is_valid_tid)(tid));
do_setmask ( tid, how, set, oldset );
- VG_(poll_signals)(tid); /* look for any newly deliverable signals */
- return 0;
+ return VG_(mk_SysRes_Success)( 0 );
default:
VG_(message)(Vg_DebugMsg,
"sigprocmask: unknown 'how' field %d", how);
- return -VKI_EINVAL;
+ return VG_(mk_SysRes_Error)( VKI_EINVAL );
}
}
@@ -1611,11 +1614,13 @@ void async_signalhandler ( Int sigNo, vki_siginfo_t *info, struct vki_ucontext *
sigNo, tid, info->si_code);
/* Update thread state properly */
- VGP_(interrupted_syscall)(tid,
- VGP_UCONTEXT_INSTR_PTR(uc),
- VGP_UCONTEXT_SYSCALL_NUM(uc),
- VGP_UCONTEXT_SYSCALL_RET(uc),
- !!(scss.scss_per_sig[sigNo].scss_flags & VKI_SA_RESTART));
+ VG_(fixup_guest_state_after_syscall_interrupted)(
+ tid,
+ VGP_UCONTEXT_INSTR_PTR(uc),
+ VGP_UCONTEXT_SYSCALL_NUM(uc),
+ VGP_UCONTEXT_SYSCALL_SYSRES(uc),
+ !!(scss.scss_per_sig[sigNo].scss_flags & VKI_SA_RESTART)
+ );
/* Set up the thread's state to deliver a signal */
if (!is_sig_ign(info->si_signo))
@@ -1985,7 +1990,8 @@ void VG_(poll_signals)(ThreadId tid)
/* If there was nothing queued, ask the kernel for a pending signal */
if (sip == NULL && VG_(sigtimedwait)(&pollset, &si, &zero) > 0) {
if (VG_(clo_trace_signals))
- VG_(message)(Vg_DebugMsg, "poll_signals: got signal %d for thread %d", si.si_signo, tid);
+ VG_(message)(Vg_DebugMsg, "poll_signals: got signal %d "
+ "for thread %d", si.si_signo, tid);
sip = &si;
}
diff --git a/coregrind/m_syscalls/Makefile.am b/coregrind/m_syscalls/Makefile.am
index 796a08223..51c7db17d 100644
--- a/coregrind/m_syscalls/Makefile.am
+++ b/coregrind/m_syscalls/Makefile.am
@@ -5,7 +5,8 @@ EXTRA_DIST = \
README_SYSCALLS.txt
noinst_HEADERS = \
- priv_syscalls.h \
+ priv_types_n_macros.h \
+ priv_syscalls-generic.h \
priv_syscalls-linux.h \
priv_syscalls-amd64-linux.h \
priv_syscalls-arm-linux.h \
@@ -15,6 +16,7 @@ noinst_LIBRARIES = libsyscalls.a
libsyscalls_a_SOURCES = \
syscall-@VG_PLATFORM@.S \
- syscalls.c \
+ syscalls-generic.c \
syscalls-@VG_OS@.c \
- syscalls-@VG_PLATFORM@.c
+ syscalls-@VG_PLATFORM@.c \
+ syscalls-main.c
diff --git a/coregrind/m_syscalls/README_SYSCALLS.txt b/coregrind/m_syscalls/README_SYSCALLS.txt
index 5c12cf776..060069305 100644
--- a/coregrind/m_syscalls/README_SYSCALLS.txt
+++ b/coregrind/m_syscalls/README_SYSCALLS.txt
@@ -1 +1,14 @@
-(put useful notes about this module in here)
+
+This module handles the complex business of handing system calls off
+to the host and then fixing up the guest state accordingly. It
+interacts complicatedly with signals and to a less extent threads.
+
+There are some important caveats regarding how to write the PRE and
+POST wrappers for syscalls. It is important to observe these, else
+you will have to track down almost impossibly obscure bugs. These
+caveats are described in comments at the top of syscalls-main.c.
+
+The main file is syscalls-main.c. It contains all the driver logic
+and a great deal of commentary. The wrappers themselves live in
+syscalls-generic.c, syscalls-${OS}.c and syscalls-${PLATFORM}.c.
+
diff --git a/coregrind/m_syscalls/priv_syscalls-generic.h b/coregrind/m_syscalls/priv_syscalls-generic.h
new file mode 100644
index 000000000..e695cf481
--- /dev/null
+++ b/coregrind/m_syscalls/priv_syscalls-generic.h
@@ -0,0 +1,324 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Private syscalls header. priv_syscalls.h ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2000-2005 Julian Seward
+ jseward@acm.org
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#ifndef __PRIV_SYSCALLS_GENERIC_H
+#define __PRIV_SYSCALLS_GENERIC_H
+
+/* requires #include "priv_types_n_macros.h" */
+
+
+// Return true if address range entirely contained within client
+// address space.
+extern
+Bool VG_(valid_client_addr)(Addr start, SizeT size, ThreadId tid,
+ const Char *syscallname);
+
+// Return true if we're allowed to use or create this fd.
+extern
+Bool VG_(fd_allowed)(Int fd, const Char *syscallname, ThreadId tid, Bool soft);
+
+extern
+void VG_(record_fd_open)(ThreadId tid, Int fd, char *pathname);
+
+// Used when killing threads -- we must not kill a thread if it's the thread
+// that would do Valgrind's final cleanup and output.
+extern
+Bool VG_(do_sigkill)(Int pid, Int tgid);
+
+/* So that it can be seen from syscalls-x86-linux.c. */
+extern
+void VG_(mmap_segment) ( Addr a, SizeT len, UInt prot,
+ UInt mm_flags, Int fd, ULong offset );
+
+
+DECL_TEMPLATE(generic,sys_ni_syscall); // * P -- unimplemented
+DECL_TEMPLATE(generic,sys_exit);
+DECL_TEMPLATE(generic,sys_fork);
+DECL_TEMPLATE(generic,sys_read);
+DECL_TEMPLATE(generic,sys_write);
+DECL_TEMPLATE(generic,sys_open);
+DECL_TEMPLATE(generic,sys_close);
+DECL_TEMPLATE(generic,sys_waitpid);
+DECL_TEMPLATE(generic,sys_creat);
+DECL_TEMPLATE(generic,sys_link);
+DECL_TEMPLATE(generic,sys_unlink);
+DECL_TEMPLATE(generic,sys_execve); // (*??) P
+DECL_TEMPLATE(generic,sys_chdir);
+DECL_TEMPLATE(generic,sys_time);
+DECL_TEMPLATE(generic,sys_mknod);
+DECL_TEMPLATE(generic,sys_chmod);
+DECL_TEMPLATE(generic,sys_lseek);
+DECL_TEMPLATE(generic,sys_getpid);
+DECL_TEMPLATE(generic,sys_alarm);
+DECL_TEMPLATE(generic,sys_pause);
+DECL_TEMPLATE(generic,sys_utime);
+DECL_TEMPLATE(generic,sys_access);
+DECL_TEMPLATE(generic,sys_kill);
+DECL_TEMPLATE(generic,sys_rename);
+DECL_TEMPLATE(generic,sys_mkdir);
+DECL_TEMPLATE(generic,sys_rmdir);
+DECL_TEMPLATE(generic,sys_dup);
+DECL_TEMPLATE(generic,sys_times);
+DECL_TEMPLATE(generic,sys_fcntl); // POSIX (but complicated)
+DECL_TEMPLATE(generic,sys_setpgid);
+DECL_TEMPLATE(generic,sys_umask);
+DECL_TEMPLATE(generic,sys_dup2);
+DECL_TEMPLATE(generic,sys_getppid);
+DECL_TEMPLATE(generic,sys_getpgrp);
+DECL_TEMPLATE(generic,sys_setsid);
+DECL_TEMPLATE(generic,sys_munmap);
+DECL_TEMPLATE(generic,sys_truncate);
+DECL_TEMPLATE(generic,sys_ftruncate);
+DECL_TEMPLATE(generic,sys_fchmod);
+DECL_TEMPLATE(generic,sys_msync);
+DECL_TEMPLATE(generic,sys_readv);
+DECL_TEMPLATE(generic,sys_writev);
+DECL_TEMPLATE(generic,sys_getsid);
+DECL_TEMPLATE(generic,sys_fdatasync);
+DECL_TEMPLATE(generic,sys_mlock);
+DECL_TEMPLATE(generic,sys_munlock);
+DECL_TEMPLATE(generic,sys_mlockall);
+DECL_TEMPLATE(generic,sys_munlockall);
+DECL_TEMPLATE(generic,sys_sched_setparam);
+DECL_TEMPLATE(generic,sys_sched_getparam);
+DECL_TEMPLATE(generic,sys_sched_rr_get_interval);
+DECL_TEMPLATE(generic,sys_sched_setscheduler);
+DECL_TEMPLATE(generic,sys_sched_getscheduler);
+DECL_TEMPLATE(generic,sys_sched_yield);
+DECL_TEMPLATE(generic,sys_sched_get_priority_max);
+DECL_TEMPLATE(generic,sys_sched_get_priority_min);
+DECL_TEMPLATE(generic,sys_nanosleep);
+DECL_TEMPLATE(generic,sys_mremap); // POSIX, but Linux arg order may be odd
+DECL_TEMPLATE(generic,sys_getuid);
+DECL_TEMPLATE(generic,sys_getgid);
+DECL_TEMPLATE(generic,sys_geteuid);
+DECL_TEMPLATE(generic,sys_getegid);
+DECL_TEMPLATE(generic,sys_getpgid);
+DECL_TEMPLATE(generic,sys_fsync);
+DECL_TEMPLATE(generic,sys_wait4);
+DECL_TEMPLATE(generic,sys_mprotect);
+DECL_TEMPLATE(generic,sys_sigprocmask);
+DECL_TEMPLATE(generic,sys_timer_create); // Linux: varies across archs?
+DECL_TEMPLATE(generic,sys_timer_settime);
+DECL_TEMPLATE(generic,sys_timer_gettime);
+DECL_TEMPLATE(generic,sys_timer_getoverrun);
+DECL_TEMPLATE(generic,sys_timer_delete);
+DECL_TEMPLATE(generic,sys_clock_settime);
+DECL_TEMPLATE(generic,sys_clock_gettime);
+DECL_TEMPLATE(generic,sys_clock_getres);
+DECL_TEMPLATE(generic,sys_clock_nanosleep);
+DECL_TEMPLATE(generic,sys_getcwd);
+DECL_TEMPLATE(generic,sys_symlink);
+DECL_TEMPLATE(generic,sys_getgroups);
+DECL_TEMPLATE(generic,sys_setgroups); // SVr4, SVID, X/OPEN, 4.3BSD
+DECL_TEMPLATE(generic,sys_chown);
+DECL_TEMPLATE(generic,sys_setuid);
+DECL_TEMPLATE(generic,sys_gettimeofday);
+DECL_TEMPLATE(generic,sys_madvise);
+DECL_TEMPLATE(generic,sys_sigpending);
+
+// These ones aren't POSIX, but are in some standard and look reasonably
+// generic, and are the same for all architectures under Linux.
+DECL_TEMPLATE(generic,sys_nice); // SVr4, SVID EXT, AT&T, X/OPEN, BSD 4.3
+DECL_TEMPLATE(generic,sys_sync); // SVr4, SVID, X/OPEN, BSD 4.3
+DECL_TEMPLATE(generic,sys_brk); // 4.3BSD
+DECL_TEMPLATE(generic,sys_acct); // SVR4, non-POSIX
+DECL_TEMPLATE(generic,sys_chroot); // SVr4, SVID, 4.4BSD, X/OPEN
+DECL_TEMPLATE(generic,sys_readlink); // X/OPEN, 4.4BSD
+DECL_TEMPLATE(generic,sys_fchdir); // SVr4, SVID, POSIX, X/OPEN, 4.4BSD
+DECL_TEMPLATE(generic,sys_getdents); // SVr4,SVID
+DECL_TEMPLATE(generic,sys_select); // 4.4BSD
+DECL_TEMPLATE(generic,sys_flock); // 4.4BSD
+DECL_TEMPLATE(generic,sys_poll); // XPG4-UNIX
+DECL_TEMPLATE(generic,sys_getrusage); // SVr4, 4.3BSD
+DECL_TEMPLATE(generic,sys_stime); // SVr4, SVID, X/OPEN
+DECL_TEMPLATE(generic,sys_settimeofday); // SVr4, 4.3BSD (non-POSIX)
+DECL_TEMPLATE(generic,sys_getpriority); // SVr4, 4.4BSD
+DECL_TEMPLATE(generic,sys_setpriority); // SVr4, 4.4BSD
+DECL_TEMPLATE(generic,sys_setitimer); // SVr4, 4.4BSD
+DECL_TEMPLATE(generic,sys_getitimer); // SVr4, 4.4BSD
+DECL_TEMPLATE(generic,sys_setreuid); // 4.3BSD
+DECL_TEMPLATE(generic,sys_setregid); // 4.3BSD
+DECL_TEMPLATE(generic,sys_fchown); // SVr4,4.3BSD
+DECL_TEMPLATE(generic,sys_setgid); // SVr4,SVID
+DECL_TEMPLATE(generic,sys_utimes); // 4.3BSD
+
+// These ones may be Linux specific... not sure. They use 16-bit gid_t and
+// uid_t types. The similarly named (minus the "16" suffix) ones below use
+// 32-bit versions of these types.
+DECL_TEMPLATE(generic,sys_setuid16); // ## P
+DECL_TEMPLATE(generic,sys_getuid16); // ## P
+DECL_TEMPLATE(generic,sys_setgid16); // ## SVr4,SVID
+DECL_TEMPLATE(generic,sys_getgid16); // ## P
+DECL_TEMPLATE(generic,sys_geteuid16); // ## P
+DECL_TEMPLATE(generic,sys_getegid16); // ## P
+DECL_TEMPLATE(generic,sys_setreuid16); // ## BSD4.3
+DECL_TEMPLATE(generic,sys_setregid16); // ## BSD4.3
+DECL_TEMPLATE(generic,sys_getgroups16); // ## P
+DECL_TEMPLATE(generic,sys_setgroups16); // ## SVr4, SVID, X/OPEN, 4.3BSD
+DECL_TEMPLATE(generic,sys_fchown16); // ## SVr4,BSD4.3
+DECL_TEMPLATE(generic,sys_chown16); // ## P
+
+// Some archs on Linux do not match the generic wrapper for sys_pipe().
+DECL_TEMPLATE(generic,sys_pipe);
+
+// May not be generic for every architecture under Linux.
+DECL_TEMPLATE(generic,sys_sigaction); // (x86) P
+
+// Funny names, not sure...
+DECL_TEMPLATE(generic,sys_newstat); // * P
+DECL_TEMPLATE(generic,sys_newlstat); // *
+DECL_TEMPLATE(generic,sys_newfstat); // * P (SVr4,BSD4.3)
+
+// For the remainder, not really sure yet
+DECL_TEMPLATE(generic,sys_ptrace); // (x86?) (almost-P)
+DECL_TEMPLATE(generic,sys_sigsuspend); // POSIX, but L (proto varies across archs)
+DECL_TEMPLATE(generic,sys_setrlimit); // SVr4, 4.3BSD
+DECL_TEMPLATE(generic,sys_ioctl); // x86? (various)
+DECL_TEMPLATE(generic,sys_old_getrlimit); // SVr4, 4.3BSD L?
+DECL_TEMPLATE(generic,sys_statfs); // * L?
+DECL_TEMPLATE(generic,sys_fstatfs); // * L?
+DECL_TEMPLATE(generic,sys_iopl); // (x86/amd64) L
+DECL_TEMPLATE(generic,sys_ipc); // (x86) L
+DECL_TEMPLATE(generic,sys_newuname); // * P
+DECL_TEMPLATE(generic,sys_init_module); // * L?
+DECL_TEMPLATE(generic,sys_quotactl); // * (?)
+DECL_TEMPLATE(generic,sys_rt_sigaction); // (x86) ()
+DECL_TEMPLATE(generic,sys_rt_sigprocmask); // * ?
+DECL_TEMPLATE(generic,sys_rt_sigpending); // * ?
+DECL_TEMPLATE(generic,sys_rt_sigtimedwait); // * ?
+DECL_TEMPLATE(generic,sys_rt_sigqueueinfo); // * ?
+DECL_TEMPLATE(generic,sys_rt_sigsuspend); // () ()
+DECL_TEMPLATE(generic,sys_pread64); // * (Unix98?)
+DECL_TEMPLATE(generic,sys_pwrite64); // * (Unix98?)
+DECL_TEMPLATE(generic,sys_capget); // * L?
+DECL_TEMPLATE(generic,sys_capset); // * L?
+DECL_TEMPLATE(generic,sys_sigaltstack); // (x86) (XPG4-UNIX)
+DECL_TEMPLATE(generic,sys_getpmsg); // (?) (?)
+DECL_TEMPLATE(generic,sys_putpmsg); // (?) (?)
+DECL_TEMPLATE(generic,sys_getrlimit); // * (?)
+DECL_TEMPLATE(generic,sys_mmap2); // (x86?) P?
+DECL_TEMPLATE(generic,sys_truncate64); // %% (P?)
+DECL_TEMPLATE(generic,sys_ftruncate64); // %% (P?)
+DECL_TEMPLATE(generic,sys_lchown); // * (L?)
+DECL_TEMPLATE(generic,sys_mincore); // * L?
+DECL_TEMPLATE(generic,sys_getdents64); // * (SVr4,SVID?)
+DECL_TEMPLATE(generic,sys_fcntl64); // * P?
+DECL_TEMPLATE(generic,sys_setxattr); // * L?
+DECL_TEMPLATE(generic,sys_lsetxattr); // * L?
+DECL_TEMPLATE(generic,sys_fsetxattr); // * L?
+DECL_TEMPLATE(generic,sys_getxattr); // * L?
+DECL_TEMPLATE(generic,sys_lgetxattr); // * L?
+DECL_TEMPLATE(generic,sys_fgetxattr); // * L?
+DECL_TEMPLATE(generic,sys_listxattr); // * L?
+DECL_TEMPLATE(generic,sys_llistxattr); // * L?
+DECL_TEMPLATE(generic,sys_flistxattr); // * L?
+DECL_TEMPLATE(generic,sys_removexattr); // * L?
+DECL_TEMPLATE(generic,sys_lremovexattr); // * L?
+DECL_TEMPLATE(generic,sys_fremovexattr); // * L?
+DECL_TEMPLATE(generic,sys_sched_setaffinity); // * L?
+DECL_TEMPLATE(generic,sys_sched_getaffinity); // * L?
+DECL_TEMPLATE(generic,sys_lookup_dcookie); // (*/32/64) L
+DECL_TEMPLATE(generic,sys_set_tid_address); // * ?
+DECL_TEMPLATE(generic,sys_statfs64); // * (?)
+DECL_TEMPLATE(generic,sys_fstatfs64); // * (?)
+DECL_TEMPLATE(generic,sys_mq_open); // * P?
+DECL_TEMPLATE(generic,sys_mq_unlink); // * P?
+DECL_TEMPLATE(generic,sys_mq_timedsend); // * P?
+DECL_TEMPLATE(generic,sys_mq_timedreceive); // * P?
+DECL_TEMPLATE(generic,sys_mq_notify); // * P?
+DECL_TEMPLATE(generic,sys_mq_getsetattr); // * P?
+
+
+
+/* ---------------------------------------------------------------------
+ Wrappers for sockets and ipc-ery. These are split into standalone
+ procedures because x86-linux hides them inside multiplexors
+ (sys_socketcall and sys_ipc).
+ ------------------------------------------------------------------ */
+
+#define TId ThreadId
+#define UW UWord
+#define SR SysRes
+
+extern void VG_(generic_PRE_sys_socketpair) ( TId, UW, UW, UW, UW );
+extern SysRes VG_(generic_POST_sys_socketpair) ( TId, SR, UW, UW, UW, UW );
+extern SysRes VG_(generic_POST_sys_socket) ( TId, SR );
+extern void VG_(generic_PRE_sys_bind) ( TId, UW, UW, UW );
+extern void VG_(generic_PRE_sys_accept) ( TId, UW, UW, UW );
+extern SysRes VG_(generic_POST_sys_accept) ( TId, SR, UW, UW, UW );
+extern void VG_(generic_PRE_sys_sendto) ( TId, UW, UW, UW, UW, UW, UW );
+extern void VG_(generic_PRE_sys_send) ( TId, UW, UW, UW );
+extern void VG_(generic_PRE_sys_recvfrom) ( TId, UW, UW, UW, UW, UW, UW );
+extern void VG_(generic_POST_sys_recvfrom) ( TId, SR, UW, UW, UW, UW, UW, UW );
+extern void VG_(generic_PRE_sys_recv) ( TId, UW, UW, UW );
+extern void VG_(generic_POST_sys_recv) ( TId, UW, UW, UW, UW );
+extern void VG_(generic_PRE_sys_connect) ( TId, UW, UW, UW );
+extern void VG_(generic_PRE_sys_setsockopt) ( TId, UW, UW, UW, UW, UW );
+extern void VG_(generic_PRE_sys_getsockopt) ( TId, UW, UW, UW, UW, UW );
+extern void VG_(generic_POST_sys_getsockopt) ( TId, SR, UW, UW, UW, UW, UW );
+extern void VG_(generic_PRE_sys_getsockname) ( TId, UW, UW, UW );
+extern void VG_(generic_POST_sys_getsockname) ( TId, SR, UW, UW, UW );
+extern void VG_(generic_PRE_sys_getpeername) ( TId, UW, UW, UW );
+extern void VG_(generic_POST_sys_getpeername) ( TId, SR, UW, UW, UW );
+extern void VG_(generic_PRE_sys_sendmsg) ( TId, UW, UW );
+extern void VG_(generic_PRE_sys_recvmsg) ( TId, UW, UW );
+extern void VG_(generic_POST_sys_recvmsg) ( TId, UW, UW );
+
+extern void VG_(generic_PRE_sys_semop) ( TId, UW, UW, UW );
+extern void VG_(generic_PRE_sys_semtimedop) ( TId, UW, UW, UW, UW );
+extern void VG_(generic_PRE_sys_semctl) ( TId, UW, UW, UW, UW );
+extern void VG_(generic_POST_sys_semctl) ( TId, UW, UW, UW, UW, UW );
+extern void VG_(generic_PRE_sys_msgsnd) ( TId, UW, UW, UW, UW );
+extern void VG_(generic_PRE_sys_msgrcv) ( TId, UW, UW, UW, UW, UW );
+extern void VG_(generic_POST_sys_msgrcv) ( TId, UW, UW, UW, UW, UW, UW );
+extern void VG_(generic_PRE_sys_msgctl) ( TId, UW, UW, UW );
+extern void VG_(generic_POST_sys_msgctl) ( TId, UW, UW, UW, UW );
+extern UWord VG_(generic_PRE_sys_shmat) ( TId, UW, UW, UW );
+extern void VG_(generic_POST_sys_shmat) ( TId, UW, UW, UW, UW );
+extern Bool VG_(generic_PRE_sys_shmdt) ( TId, UW );
+extern void VG_(generic_POST_sys_shmdt) ( TId, UW, UW );
+extern void VG_(generic_PRE_sys_shmctl) ( TId, UW, UW, UW );
+extern void VG_(generic_POST_sys_shmctl) ( TId, UW, UW, UW, UW );
+
+#undef TId
+#undef UW
+#undef SR
+
+
+/////////////////////////////////////////////////////////////////
+
+
+#endif // __PRIV_SYSCALLS_GENERIC_H
+
+/*--------------------------------------------------------------------*/
+/*--- end ---*/
+/*--------------------------------------------------------------------*/
+
diff --git a/coregrind/m_syscalls/priv_syscalls-linux.h b/coregrind/m_syscalls/priv_syscalls-linux.h
index 86223cf60..7747196b3 100644
--- a/coregrind/m_syscalls/priv_syscalls-linux.h
+++ b/coregrind/m_syscalls/priv_syscalls-linux.h
@@ -31,68 +31,60 @@
#ifndef __PRIV_SYSCALLS_LINUX_H
#define __PRIV_SYSCALLS_LINUX_H
-// Macros for adding Linux-specific, arch-independent wrappers to a syscall
-// table.
-#define LINX_(const, name) SYS_WRAPPER_ENTRY_X_(vgOS_linux, const, name)
-#define LINXY(const, name) SYS_WRAPPER_ENTRY_XY(vgOS_linux, const, name)
-
-// The following syscall wrappers are Linux-specific, but arch-independent.
-#define LINUX_SYSCALL_WRAPPER(x) \
- extern UInt VGO_(linux_##x##_flags); \
- extern void VGO_(linux_##x##_before)(ThreadId tid, ThreadState *tst); \
- extern void VGO_(linux_##x##_after) (ThreadId tid, ThreadState *tst)
-
-LINUX_SYSCALL_WRAPPER(sys_exit_group);
-
-LINUX_SYSCALL_WRAPPER(sys_mount);
-LINUX_SYSCALL_WRAPPER(sys_oldumount);
-LINUX_SYSCALL_WRAPPER(sys_umount);
-
-LINUX_SYSCALL_WRAPPER(sys_llseek);
-LINUX_SYSCALL_WRAPPER(sys_adjtimex);
-
-LINUX_SYSCALL_WRAPPER(sys_setfsuid16);
-LINUX_SYSCALL_WRAPPER(sys_setfsgid16);
-LINUX_SYSCALL_WRAPPER(sys_setresuid16); // man page says "non-standard";
-LINUX_SYSCALL_WRAPPER(sys_getresuid16);
-LINUX_SYSCALL_WRAPPER(sys_setresgid16); // man page says "non-standard"
-LINUX_SYSCALL_WRAPPER(sys_getresgid16);
-
-LINUX_SYSCALL_WRAPPER(sys_setfsuid);
-LINUX_SYSCALL_WRAPPER(sys_setfsgid);
-LINUX_SYSCALL_WRAPPER(sys_setresuid); // man page says "non-standard"
-LINUX_SYSCALL_WRAPPER(sys_getresuid);
-LINUX_SYSCALL_WRAPPER(sys_setresgid); // man page says "non-standard"
-LINUX_SYSCALL_WRAPPER(sys_getresgid);
-
-LINUX_SYSCALL_WRAPPER(sys_ioperm);
-LINUX_SYSCALL_WRAPPER(sys_syslog);
-LINUX_SYSCALL_WRAPPER(sys_vhangup);
-LINUX_SYSCALL_WRAPPER(sys_sysinfo);
-LINUX_SYSCALL_WRAPPER(sys_personality);
-LINUX_SYSCALL_WRAPPER(sys_sysctl);
-LINUX_SYSCALL_WRAPPER(sys_prctl);
-
-LINUX_SYSCALL_WRAPPER(sys_sendfile);
-LINUX_SYSCALL_WRAPPER(sys_sendfile64);
-LINUX_SYSCALL_WRAPPER(sys_futex);
-
-LINUX_SYSCALL_WRAPPER(sys_epoll_create);
-LINUX_SYSCALL_WRAPPER(sys_epoll_ctl);
-LINUX_SYSCALL_WRAPPER(sys_epoll_wait);
-
-LINUX_SYSCALL_WRAPPER(sys_gettid);
-LINUX_SYSCALL_WRAPPER(sys_tkill);
-LINUX_SYSCALL_WRAPPER(sys_tgkill);
-
-LINUX_SYSCALL_WRAPPER(sys_fadvise64);
-LINUX_SYSCALL_WRAPPER(sys_fadvise64_64);
-
-LINUX_SYSCALL_WRAPPER(sys_io_setup);
-LINUX_SYSCALL_WRAPPER(sys_io_destroy);
-LINUX_SYSCALL_WRAPPER(sys_io_getevents);
-LINUX_SYSCALL_WRAPPER(sys_io_submit);
-LINUX_SYSCALL_WRAPPER(sys_io_cancel);
+/* requires #include "priv_types_n_macros.h" */
+
+
+DECL_TEMPLATE(linux,sys_exit_group);
+
+DECL_TEMPLATE(linux,sys_mount);
+DECL_TEMPLATE(linux,sys_oldumount);
+DECL_TEMPLATE(linux,sys_umount);
+
+DECL_TEMPLATE(linux,sys_llseek);
+DECL_TEMPLATE(linux,sys_adjtimex);
+
+DECL_TEMPLATE(linux,sys_setfsuid16);
+DECL_TEMPLATE(linux,sys_setfsgid16);
+DECL_TEMPLATE(linux,sys_setresuid16); // man page says "non-standard";
+DECL_TEMPLATE(linux,sys_getresuid16);
+DECL_TEMPLATE(linux,sys_setresgid16); // man page says "non-standard"
+DECL_TEMPLATE(linux,sys_getresgid16);
+
+DECL_TEMPLATE(linux,sys_setfsuid);
+DECL_TEMPLATE(linux,sys_setfsgid);
+DECL_TEMPLATE(linux,sys_setresuid); // man page says "non-standard"
+DECL_TEMPLATE(linux,sys_getresuid);
+DECL_TEMPLATE(linux,sys_setresgid); // man page says "non-standard"
+DECL_TEMPLATE(linux,sys_getresgid);
+
+DECL_TEMPLATE(linux,sys_ioperm);
+DECL_TEMPLATE(linux,sys_syslog);
+DECL_TEMPLATE(linux,sys_vhangup);
+DECL_TEMPLATE(linux,sys_sysinfo);
+DECL_TEMPLATE(linux,sys_personality);
+DECL_TEMPLATE(linux,sys_sysctl);
+DECL_TEMPLATE(linux,sys_prctl);
+
+DECL_TEMPLATE(linux,sys_sendfile);
+DECL_TEMPLATE(linux,sys_sendfile64);
+DECL_TEMPLATE(linux,sys_futex);
+
+DECL_TEMPLATE(linux,sys_epoll_create);
+DECL_TEMPLATE(linux,sys_epoll_ctl);
+DECL_TEMPLATE(linux,sys_epoll_wait);
+
+DECL_TEMPLATE(linux,sys_gettid);
+DECL_TEMPLATE(linux,sys_tkill);
+DECL_TEMPLATE(linux,sys_tgkill);
+
+DECL_TEMPLATE(linux,sys_fadvise64);
+DECL_TEMPLATE(linux,sys_fadvise64_64);
+
+DECL_TEMPLATE(linux,sys_io_setup);
+DECL_TEMPLATE(linux,sys_io_destroy);
+DECL_TEMPLATE(linux,sys_io_getevents);
+DECL_TEMPLATE(linux,sys_io_submit);
+DECL_TEMPLATE(linux,sys_io_cancel);
#endif // __PRIV_SYSCALLS_LINUX_H
diff --git a/coregrind/m_syscalls/priv_syscalls-main.h b/coregrind/m_syscalls/priv_syscalls-main.h
new file mode 100644
index 000000000..80823fdd0
--- /dev/null
+++ b/coregrind/m_syscalls/priv_syscalls-main.h
@@ -0,0 +1,43 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Private exports of syscalls-main.c. priv_syscalls-main.h ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2000-2005 Nicholas Nethercote
+ njn@valgrind.org
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#ifndef __PRIV_SYSCALLS_MAIN_H
+#define __PRIV_SYSCALLS_MAIN_H
+
+/* Back up a thread so as to restart a system call. */
+extern
+void VG_(fixup_guest_state_to_restart_syscall) ( ThreadArchState* arch );
+
+#endif // __PRIV_SYSCALLS_MAIN_H
+
+/*--------------------------------------------------------------------*/
+/*--- end priv_syscalls-main.h ---*/
+/*--------------------------------------------------------------------*/
+
diff --git a/coregrind/m_syscalls/priv_syscalls-x86-linux.h b/coregrind/m_syscalls/priv_syscalls-x86-linux.h
index 69218cecb..1c6fc97f2 100644
--- a/coregrind/m_syscalls/priv_syscalls-x86-linux.h
+++ b/coregrind/m_syscalls/priv_syscalls-x86-linux.h
@@ -31,23 +31,6 @@
#ifndef __PRIV_SYSCALLS_X86_LINUX_H
#define __PRIV_SYSCALLS_X86_LINUX_H
-// Accessors for the ThreadArchState
-#define VGP_SYSCALL_NUM guest_EAX
-#define VGP_SYSCALL_ARG1 guest_EBX
-#define VGP_SYSCALL_ARG2 guest_ECX
-#define VGP_SYSCALL_ARG3 guest_EDX
-#define VGP_SYSCALL_ARG4 guest_ESI
-#define VGP_SYSCALL_ARG5 guest_EDI
-#define VGP_SYSCALL_ARG6 guest_EBP
-#define VGP_SYSCALL_RET guest_EAX
-
-// Setting a syscall result
-#define VGP_SET_SYSCALL_RESULT(regs, val) ((regs).vex.guest_EAX = (val))
-
-// For informing tools that a syscall result has been set.
-#define VGP_TRACK_SYSCALL_RETVAL(zztid) \
- VG_TRACK( post_reg_write, Vg_CoreSysCall, zztid, O_SYSCALL_RET, sizeof(UWord) );
-
#endif // __PRIV_SYSCALLS_X86_LINUX_H
/*--------------------------------------------------------------------*/
diff --git a/coregrind/m_syscalls/priv_syscalls.h b/coregrind/m_syscalls/priv_syscalls.h
deleted file mode 100644
index c60b57933..000000000
--- a/coregrind/m_syscalls/priv_syscalls.h
+++ /dev/null
@@ -1,515 +0,0 @@
-/*--------------------------------------------------------------------*/
-/*--- Private syscalls header. priv_syscalls.h ---*/
-/*--------------------------------------------------------------------*/
-
-/*
- This file is part of Valgrind, a dynamic binary instrumentation
- framework.
-
- Copyright (C) 2000-2005 Julian Seward
- jseward@acm.org
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307, USA.
-
- The GNU General Public License is contained in the file COPYING.
-*/
-
-#ifndef __PRIV_SYSCALLS_H
-#define __PRIV_SYSCALLS_H
-
-#include "pub_core_options.h"
-#include "pub_core_signals.h"
-
-#if defined(VGO_linux)
-# include "priv_syscalls-linux.h"
-#else
-# error Unknown OS
-#endif
-
-#if defined(VGP_amd64_linux)
-# include "priv_syscalls-amd64-linux.h"
-#elif defined(VGP_arm_linux)
-# include "priv_syscalls-arm-linux.h"
-#elif defined(VGP_x86_linux)
-# include "priv_syscalls-x86-linux.h"
-#else
-# error Unknown platform
-#endif
-
-#include "vki_unistd.h"
-
-// Offsets for the shadow state
-#define O_SYSCALL_NUM (offsetof(VexGuestArchState, VGP_SYSCALL_NUM))
-#define O_SYSCALL_ARG1 (offsetof(VexGuestArchState, VGP_SYSCALL_ARG1))
-#define O_SYSCALL_ARG2 (offsetof(VexGuestArchState, VGP_SYSCALL_ARG2))
-#define O_SYSCALL_ARG3 (offsetof(VexGuestArchState, VGP_SYSCALL_ARG3))
-#define O_SYSCALL_ARG4 (offsetof(VexGuestArchState, VGP_SYSCALL_ARG4))
-#define O_SYSCALL_ARG5 (offsetof(VexGuestArchState, VGP_SYSCALL_ARG5))
-#define O_SYSCALL_ARG6 (offsetof(VexGuestArchState, VGP_SYSCALL_ARG6))
-#define O_SYSCALL_RET (offsetof(VexGuestArchState, VGP_SYSCALL_RET))
-
-// The syscall table
-struct SyscallTableEntry {
- UInt *flags_ptr;
- void (*before)(ThreadId tid, ThreadState *tst /*, UInt *flags*/);
- void (*after) (ThreadId tid, ThreadState *tst);
-};
-
-/* This table is the mapping from __NR_xxx syscall numbers to the PRE/POST
- wrappers for the relevant syscalls used in the OS kernel for that number.
- Note that the constant names don't always match the wrapper names in a
- straightforward way. For example, on x86/Linux:
-
- __NR_lchown --> sys_lchown16()
- __NR_lchown32 --> sys_lchown()
- __NR_select --> old_select()
- __NR__newselect --> sys_select()
-*/
-extern const struct SyscallTableEntry VGA_(syscall_table)[];
-
-extern const UInt VGA_(syscall_table_size);
-
-extern Int VG_(clone) ( Int (*fn)(void *), void *stack, Int flags, void *arg,
- Int *child_tid, Int *parent_tid, vki_modify_ldt_t * );
-
-/*
- Perform a syscall on behalf of a client thread, using a specific
- signal mask. On completion, the signal mask is set to restore_mask
- (which presumably blocks almost everything). If a signal happens
- during the syscall, the handler should call
- VGA_(interrupted_syscall)() to adjust the thread's context to do the
- right thing.
-*/
-extern void VGA_(client_syscall)(Int syscallno, ThreadState *tst,
- const vki_sigset_t *syscall_mask);
-
-/* Simple Valgrind-internal atfork mechanism */
-extern void VG_(do_atfork_pre) (ThreadId tid);
-extern void VG_(do_atfork_parent)(ThreadId tid);
-extern void VG_(do_atfork_child) (ThreadId tid);
-
-// Return true if address range entirely contained within client
-// address space.
-Bool VG_(valid_client_addr)(Addr start, SizeT size, ThreadId tid,
- const Char *syscallname);
-
-// Return true if we're allowed to use or create this fd.
-Bool VG_(fd_allowed)(Int fd, const Char *syscallname, ThreadId tid, Bool soft);
-
-void VG_(record_fd_open)(ThreadId tid, Int fd, char *pathname);
-
-// Used when killing threads -- we must not kill a thread if it's the thread
-// that would do Valgrind's final cleanup and output.
-Bool VG_(do_sigkill)(Int pid, Int tgid);
-
-// Flags describing syscall wrappers
-#define Special (1 << 0) /* handled specially */
-#define MayBlock (1 << 1) /* may block */
-#define PostOnFail (1 << 2) /* call POST() function on failure */
-#define PadAddr (1 << 3) /* pad+unpad address space around syscall */
-#define Done (1 << 4) /* used if a PRE() did the syscall */
-
-// Templates for generating the PRE and POST macros. For ones that must be
-// publically visible, use an empty 'qual', 'prefix' should start with
-// "vgArch_" or similar, and there should be corresponding global
-// declarations (like the GEN_SYSCALL_WRAPPER ones below). Otherwise, use
-// "static" for 'qual', and "vgArch_" should not be in the 'prefix'.
-#define PRE_TEMPLATE(qual, prefix, name, f) \
- qual UInt prefix##_##name##_flags = f; \
- qual void prefix##_##name##_before(ThreadId tid, ThreadState *tst)
-#define POST_TEMPLATE(qual, prefix, name) \
- qual void prefix##_##name##_after (ThreadId tid, ThreadState *tst)
-
-// This macro is used to write other macros which making writing syscall
-// tables easier.
-#define SYS_WRAPPER_ENTRY_X_(prefix, const, name) \
- [const] = { &prefix##_##name##_flags, \
- prefix##_##name##_before, NULL }
-#define SYS_WRAPPER_ENTRY_XY(prefix, const, name) \
- [const] = { &prefix##_##name##_flags, \
- prefix##_##name##_before, \
- prefix##_##name##_after }
-
-// Macros for adding generic wrappers to a syscall table.
-#define GENX_(const, name) SYS_WRAPPER_ENTRY_X_(vgArch_gen, const, name)
-#define GENXY(const, name) SYS_WRAPPER_ENTRY_XY(vgArch_gen, const, name)
-
-// Space-saving macros for syscall PRE() and POST() wrappers
-#define RES ((tst->arch).vex.VGP_SYSCALL_RET)
-#define SYSNO ((tst->arch).vex.VGP_SYSCALL_NUM)
-#define ARG1 ((tst->arch).vex.VGP_SYSCALL_ARG1)
-#define ARG2 ((tst->arch).vex.VGP_SYSCALL_ARG2)
-#define ARG3 ((tst->arch).vex.VGP_SYSCALL_ARG3)
-#define ARG4 ((tst->arch).vex.VGP_SYSCALL_ARG4)
-#define ARG5 ((tst->arch).vex.VGP_SYSCALL_ARG5)
-#define ARG6 ((tst->arch).vex.VGP_SYSCALL_ARG6)
-
-// For setting the result of a syscall in a wrapper
-#define SET_RESULT(val) \
- do { VGP_SET_SYSCALL_RESULT(tst->arch, (val)); \
- tst->syscall_result_set = True; \
- } while (0)
-
-#define PRINT(format, args...) \
- if (VG_(clo_trace_syscalls)) \
- VG_(printf)(format, ## args)
-
-// Generic (platform-independent) syscall wrappers. These are generally
-// POSIX or something like that; those that are not POSIX are annotated
-// with what standards they are part of, as stated in the Linux man pages.
-// For many of them, it's unclear if they are generic, or Linux-specific, or
-// x86/Linux-specific, or something else again.
-//
-// Nb: This list may change over time... ones thought at first to be generic
-// may turn out not to be, and so be moved into OS-specific or
-// platform-specific files. If there's any doubt, I'm leaving them in here.
-//
-// Nb 2: if porting to a new OS, you should really check all these generic
-// wrappers to make sure they match your OS, painful as it might be.
-//
-// For each generic ("gen") wrapper, we declare the pre-wrapper, the
-// post-wrapper (which is actually not always needed), and the associated
-// flags.
-#define GEN_SYSCALL_WRAPPER(x) \
- extern UInt VGA_(gen_##x##_flags); \
- extern void VGA_(gen_##x##_before)(ThreadId tid, ThreadState *tst); \
- extern void VGA_(gen_##x##_after) (ThreadId tid, ThreadState *tst)
-
-GEN_SYSCALL_WRAPPER(sys_ni_syscall); // * P -- unimplemented
-GEN_SYSCALL_WRAPPER(sys_exit);
-GEN_SYSCALL_WRAPPER(sys_fork);
-GEN_SYSCALL_WRAPPER(sys_read);
-GEN_SYSCALL_WRAPPER(sys_write);
-GEN_SYSCALL_WRAPPER(sys_open);
-GEN_SYSCALL_WRAPPER(sys_close);
-GEN_SYSCALL_WRAPPER(sys_waitpid);
-GEN_SYSCALL_WRAPPER(sys_creat);
-GEN_SYSCALL_WRAPPER(sys_link);
-GEN_SYSCALL_WRAPPER(sys_unlink);
-GEN_SYSCALL_WRAPPER(sys_execve); // (*??) P
-GEN_SYSCALL_WRAPPER(sys_chdir);
-GEN_SYSCALL_WRAPPER(sys_time);
-GEN_SYSCALL_WRAPPER(sys_mknod);
-GEN_SYSCALL_WRAPPER(sys_chmod);
-GEN_SYSCALL_WRAPPER(sys_lseek);
-GEN_SYSCALL_WRAPPER(sys_getpid);
-GEN_SYSCALL_WRAPPER(sys_alarm);
-GEN_SYSCALL_WRAPPER(sys_pause);
-GEN_SYSCALL_WRAPPER(sys_utime);
-GEN_SYSCALL_WRAPPER(sys_access);
-GEN_SYSCALL_WRAPPER(sys_kill);
-GEN_SYSCALL_WRAPPER(sys_rename);
-GEN_SYSCALL_WRAPPER(sys_mkdir);
-GEN_SYSCALL_WRAPPER(sys_rmdir);
-GEN_SYSCALL_WRAPPER(sys_dup);
-GEN_SYSCALL_WRAPPER(sys_times);
-GEN_SYSCALL_WRAPPER(sys_fcntl); // POSIX (but complicated)
-GEN_SYSCALL_WRAPPER(sys_setpgid);
-GEN_SYSCALL_WRAPPER(sys_umask);
-GEN_SYSCALL_WRAPPER(sys_dup2);
-GEN_SYSCALL_WRAPPER(sys_getppid);
-GEN_SYSCALL_WRAPPER(sys_getpgrp);
-GEN_SYSCALL_WRAPPER(sys_setsid);
-GEN_SYSCALL_WRAPPER(sys_munmap);
-GEN_SYSCALL_WRAPPER(sys_truncate);
-GEN_SYSCALL_WRAPPER(sys_ftruncate);
-GEN_SYSCALL_WRAPPER(sys_fchmod);
-GEN_SYSCALL_WRAPPER(sys_msync);
-GEN_SYSCALL_WRAPPER(sys_readv);
-GEN_SYSCALL_WRAPPER(sys_writev);
-GEN_SYSCALL_WRAPPER(sys_getsid);
-GEN_SYSCALL_WRAPPER(sys_fdatasync);
-GEN_SYSCALL_WRAPPER(sys_mlock);
-GEN_SYSCALL_WRAPPER(sys_munlock);
-GEN_SYSCALL_WRAPPER(sys_mlockall);
-GEN_SYSCALL_WRAPPER(sys_munlockall);
-GEN_SYSCALL_WRAPPER(sys_sched_setparam);
-GEN_SYSCALL_WRAPPER(sys_sched_getparam);
-GEN_SYSCALL_WRAPPER(sys_sched_rr_get_interval);
-GEN_SYSCALL_WRAPPER(sys_sched_setscheduler);
-GEN_SYSCALL_WRAPPER(sys_sched_getscheduler);
-GEN_SYSCALL_WRAPPER(sys_sched_yield);
-GEN_SYSCALL_WRAPPER(sys_sched_get_priority_max);
-GEN_SYSCALL_WRAPPER(sys_sched_get_priority_min);
-GEN_SYSCALL_WRAPPER(sys_nanosleep);
-GEN_SYSCALL_WRAPPER(sys_mremap); // POSIX, but Linux arg order may be odd
-GEN_SYSCALL_WRAPPER(sys_getuid);
-GEN_SYSCALL_WRAPPER(sys_getgid);
-GEN_SYSCALL_WRAPPER(sys_geteuid);
-GEN_SYSCALL_WRAPPER(sys_getegid);
-GEN_SYSCALL_WRAPPER(sys_getpgid);
-GEN_SYSCALL_WRAPPER(sys_fsync);
-GEN_SYSCALL_WRAPPER(sys_wait4);
-GEN_SYSCALL_WRAPPER(sys_mprotect);
-GEN_SYSCALL_WRAPPER(sys_sigprocmask);
-GEN_SYSCALL_WRAPPER(sys_timer_create); // Linux: varies across archs?
-GEN_SYSCALL_WRAPPER(sys_timer_settime);
-GEN_SYSCALL_WRAPPER(sys_timer_gettime);
-GEN_SYSCALL_WRAPPER(sys_timer_getoverrun);
-GEN_SYSCALL_WRAPPER(sys_timer_delete);
-GEN_SYSCALL_WRAPPER(sys_clock_settime);
-GEN_SYSCALL_WRAPPER(sys_clock_gettime);
-GEN_SYSCALL_WRAPPER(sys_clock_getres);
-GEN_SYSCALL_WRAPPER(sys_clock_nanosleep);
-GEN_SYSCALL_WRAPPER(sys_getcwd);
-GEN_SYSCALL_WRAPPER(sys_symlink);
-GEN_SYSCALL_WRAPPER(sys_getgroups);
-GEN_SYSCALL_WRAPPER(sys_setgroups); // SVr4, SVID, X/OPEN, 4.3BSD
-GEN_SYSCALL_WRAPPER(sys_chown);
-GEN_SYSCALL_WRAPPER(sys_setuid);
-GEN_SYSCALL_WRAPPER(sys_gettimeofday);
-GEN_SYSCALL_WRAPPER(sys_madvise);
-GEN_SYSCALL_WRAPPER(sys_sigpending);
-
-// These ones aren't POSIX, but are in some standard and look reasonably
-// generic, and are the same for all architectures under Linux.
-GEN_SYSCALL_WRAPPER(sys_nice); // SVr4, SVID EXT, AT&T, X/OPEN, BSD 4.3
-GEN_SYSCALL_WRAPPER(sys_sync); // SVr4, SVID, X/OPEN, BSD 4.3
-GEN_SYSCALL_WRAPPER(sys_brk); // 4.3BSD
-GEN_SYSCALL_WRAPPER(sys_acct); // SVR4, non-POSIX
-GEN_SYSCALL_WRAPPER(sys_chroot); // SVr4, SVID, 4.4BSD, X/OPEN
-GEN_SYSCALL_WRAPPER(sys_readlink); // X/OPEN, 4.4BSD
-GEN_SYSCALL_WRAPPER(sys_fchdir); // SVr4, SVID, POSIX, X/OPEN, 4.4BSD
-GEN_SYSCALL_WRAPPER(sys_getdents); // SVr4,SVID
-GEN_SYSCALL_WRAPPER(sys_select); // 4.4BSD
-GEN_SYSCALL_WRAPPER(sys_flock); // 4.4BSD
-GEN_SYSCALL_WRAPPER(sys_poll); // XPG4-UNIX
-GEN_SYSCALL_WRAPPER(sys_getrusage); // SVr4, 4.3BSD
-GEN_SYSCALL_WRAPPER(sys_stime); // SVr4, SVID, X/OPEN
-GEN_SYSCALL_WRAPPER(sys_settimeofday); // SVr4, 4.3BSD (non-POSIX)
-GEN_SYSCALL_WRAPPER(sys_getpriority); // SVr4, 4.4BSD
-GEN_SYSCALL_WRAPPER(sys_setpriority); // SVr4, 4.4BSD
-GEN_SYSCALL_WRAPPER(sys_setitimer); // SVr4, 4.4BSD
-GEN_SYSCALL_WRAPPER(sys_getitimer); // SVr4, 4.4BSD
-GEN_SYSCALL_WRAPPER(sys_setreuid); // 4.3BSD
-GEN_SYSCALL_WRAPPER(sys_setregid); // 4.3BSD
-GEN_SYSCALL_WRAPPER(sys_fchown); // SVr4,4.3BSD
-GEN_SYSCALL_WRAPPER(sys_setgid); // SVr4,SVID
-GEN_SYSCALL_WRAPPER(sys_utimes); // 4.3BSD
-
-// These ones may be Linux specific... not sure. They use 16-bit gid_t and
-// uid_t types. The similarly named (minus the "16" suffix) ones below use
-// 32-bit versions of these types.
-GEN_SYSCALL_WRAPPER(sys_setuid16); // ## P
-GEN_SYSCALL_WRAPPER(sys_getuid16); // ## P
-GEN_SYSCALL_WRAPPER(sys_setgid16); // ## SVr4,SVID
-GEN_SYSCALL_WRAPPER(sys_getgid16); // ## P
-GEN_SYSCALL_WRAPPER(sys_geteuid16); // ## P
-GEN_SYSCALL_WRAPPER(sys_getegid16); // ## P
-GEN_SYSCALL_WRAPPER(sys_setreuid16); // ## BSD4.3
-GEN_SYSCALL_WRAPPER(sys_setregid16); // ## BSD4.3
-GEN_SYSCALL_WRAPPER(sys_getgroups16); // ## P
-GEN_SYSCALL_WRAPPER(sys_setgroups16); // ## SVr4, SVID, X/OPEN, 4.3BSD
-GEN_SYSCALL_WRAPPER(sys_fchown16); // ## SVr4,BSD4.3
-GEN_SYSCALL_WRAPPER(sys_chown16); // ## P
-
-// Linux's funny many-in-one socketcall is certainly not generic, but I
-// didn't want to move it until necessary because it's big and has a lot of
-// associated junk.
-GEN_SYSCALL_WRAPPER(sys_socketcall);
-
-// Some archs on Linux do not match the generic wrapper for sys_pipe().
-GEN_SYSCALL_WRAPPER(sys_pipe);
-
-// May not be generic for every architecture under Linux.
-GEN_SYSCALL_WRAPPER(sys_sigaction); // (x86) P
-
-// Funny names, not sure...
-GEN_SYSCALL_WRAPPER(sys_newstat); // * P
-GEN_SYSCALL_WRAPPER(sys_newlstat); // *
-GEN_SYSCALL_WRAPPER(sys_newfstat); // * P (SVr4,BSD4.3)
-
-// For the remainder, not really sure yet
-GEN_SYSCALL_WRAPPER(old_mmap); // x86, weird arg passing
-GEN_SYSCALL_WRAPPER(sys_ptrace); // (x86?) (almost-P)
-GEN_SYSCALL_WRAPPER(sys_sigsuspend); // POSIX, but L (proto varies across archs)
-GEN_SYSCALL_WRAPPER(sys_setrlimit); // SVr4, 4.3BSD
-GEN_SYSCALL_WRAPPER(sys_ioctl); // x86? (various)
-GEN_SYSCALL_WRAPPER(sys_old_getrlimit); // SVr4, 4.3BSD L?
-GEN_SYSCALL_WRAPPER(sys_statfs); // * L?
-GEN_SYSCALL_WRAPPER(sys_fstatfs); // * L?
-GEN_SYSCALL_WRAPPER(sys_iopl); // (x86/amd64) L
-GEN_SYSCALL_WRAPPER(sys_ipc); // (x86) L
-GEN_SYSCALL_WRAPPER(sys_newuname); // * P
-GEN_SYSCALL_WRAPPER(sys_init_module); // * L?
-GEN_SYSCALL_WRAPPER(sys_quotactl); // * (?)
-GEN_SYSCALL_WRAPPER(sys_rt_sigaction); // (x86) ()
-GEN_SYSCALL_WRAPPER(sys_rt_sigprocmask); // * ?
-GEN_SYSCALL_WRAPPER(sys_rt_sigpending); // * ?
-GEN_SYSCALL_WRAPPER(sys_rt_sigtimedwait); // * ?
-GEN_SYSCALL_WRAPPER(sys_rt_sigqueueinfo); // * ?
-GEN_SYSCALL_WRAPPER(sys_rt_sigsuspend); // () ()
-GEN_SYSCALL_WRAPPER(sys_pread64); // * (Unix98?)
-GEN_SYSCALL_WRAPPER(sys_pwrite64); // * (Unix98?)
-GEN_SYSCALL_WRAPPER(sys_capget); // * L?
-GEN_SYSCALL_WRAPPER(sys_capset); // * L?
-GEN_SYSCALL_WRAPPER(sys_sigaltstack); // (x86) (XPG4-UNIX)
-GEN_SYSCALL_WRAPPER(sys_getpmsg); // (?) (?)
-GEN_SYSCALL_WRAPPER(sys_putpmsg); // (?) (?)
-GEN_SYSCALL_WRAPPER(sys_getrlimit); // * (?)
-GEN_SYSCALL_WRAPPER(sys_mmap2); // (x86?) P?
-GEN_SYSCALL_WRAPPER(sys_truncate64); // %% (P?)
-GEN_SYSCALL_WRAPPER(sys_ftruncate64); // %% (P?)
-GEN_SYSCALL_WRAPPER(sys_stat64); // %% (?)
-GEN_SYSCALL_WRAPPER(sys_lstat64); // %% (?)
-GEN_SYSCALL_WRAPPER(sys_fstat64); // %% (?)
-GEN_SYSCALL_WRAPPER(sys_lchown); // * (L?)
-GEN_SYSCALL_WRAPPER(sys_mincore); // * L?
-GEN_SYSCALL_WRAPPER(sys_getdents64); // * (SVr4,SVID?)
-GEN_SYSCALL_WRAPPER(sys_fcntl64); // * P?
-GEN_SYSCALL_WRAPPER(sys_setxattr); // * L?
-GEN_SYSCALL_WRAPPER(sys_lsetxattr); // * L?
-GEN_SYSCALL_WRAPPER(sys_fsetxattr); // * L?
-GEN_SYSCALL_WRAPPER(sys_getxattr); // * L?
-GEN_SYSCALL_WRAPPER(sys_lgetxattr); // * L?
-GEN_SYSCALL_WRAPPER(sys_fgetxattr); // * L?
-GEN_SYSCALL_WRAPPER(sys_listxattr); // * L?
-GEN_SYSCALL_WRAPPER(sys_llistxattr); // * L?
-GEN_SYSCALL_WRAPPER(sys_flistxattr); // * L?
-GEN_SYSCALL_WRAPPER(sys_removexattr); // * L?
-GEN_SYSCALL_WRAPPER(sys_lremovexattr); // * L?
-GEN_SYSCALL_WRAPPER(sys_fremovexattr); // * L?
-GEN_SYSCALL_WRAPPER(sys_sched_setaffinity); // * L?
-GEN_SYSCALL_WRAPPER(sys_sched_getaffinity); // * L?
-GEN_SYSCALL_WRAPPER(sys_lookup_dcookie); // (*/32/64) L
-GEN_SYSCALL_WRAPPER(sys_set_tid_address); // * ?
-GEN_SYSCALL_WRAPPER(sys_statfs64); // * (?)
-GEN_SYSCALL_WRAPPER(sys_fstatfs64); // * (?)
-GEN_SYSCALL_WRAPPER(sys_mq_open); // * P?
-GEN_SYSCALL_WRAPPER(sys_mq_unlink); // * P?
-GEN_SYSCALL_WRAPPER(sys_mq_timedsend); // * P?
-GEN_SYSCALL_WRAPPER(sys_mq_timedreceive); // * P?
-GEN_SYSCALL_WRAPPER(sys_mq_notify); // * P?
-GEN_SYSCALL_WRAPPER(sys_mq_getsetattr); // * P?
-
-#undef GEN_SYSCALL_WRAPPER
-
-// Macros used in syscall wrappers
-/* PRRAn == "pre-register-read-argument"
- PRRSN == "pre-register-read-syscall"
-*/
-
-#define PRRSN \
- VG_(tdict).track_pre_reg_read(Vg_CoreSysCall, tid, "(syscallno)", \
- O_SYSCALL_NUM, sizeof(UWord));
-#define PRRAn(n,s,t,a) \
- VG_(tdict).track_pre_reg_read(Vg_CoreSysCall, tid, s"("#a")", \
- O_SYSCALL_ARG##n, sizeof(t));
-#define PRE_REG_READ0(tr, s) \
- if (VG_(tdict).track_pre_reg_read) { \
- PRRSN; \
- }
-#define PRE_REG_READ1(tr, s, t1, a1) \
- if (VG_(tdict).track_pre_reg_read) { \
- PRRSN; \
- PRRAn(1,s,t1,a1); \
- }
-#define PRE_REG_READ2(tr, s, t1, a1, t2, a2) \
- if (VG_(tdict).track_pre_reg_read) { \
- PRRSN; \
- PRRAn(1,s,t1,a1); PRRAn(2,s,t2,a2); \
- }
-#define PRE_REG_READ3(tr, s, t1, a1, t2, a2, t3, a3) \
- if (VG_(tdict).track_pre_reg_read) { \
- PRRSN; \
- PRRAn(1,s,t1,a1); PRRAn(2,s,t2,a2); PRRAn(3,s,t3,a3); \
- }
-#define PRE_REG_READ4(tr, s, t1, a1, t2, a2, t3, a3, t4, a4) \
- if (VG_(tdict).track_pre_reg_read) { \
- PRRSN; \
- PRRAn(1,s,t1,a1); PRRAn(2,s,t2,a2); PRRAn(3,s,t3,a3); \
- PRRAn(4,s,t4,a4); \
- }
-#define PRE_REG_READ5(tr, s, t1, a1, t2, a2, t3, a3, t4, a4, t5, a5) \
- if (VG_(tdict).track_pre_reg_read) { \
- PRRSN; \
- PRRAn(1,s,t1,a1); PRRAn(2,s,t2,a2); PRRAn(3,s,t3,a3); \
- PRRAn(4,s,t4,a4); PRRAn(5,s,t5,a5); \
- }
-#define PRE_REG_READ6(tr, s, t1, a1, t2, a2, t3, a3, t4, a4, t5, a5, t6, a6) \
- if (VG_(tdict).track_pre_reg_read) { \
- PRRSN; \
- PRRAn(1,s,t1,a1); PRRAn(2,s,t2,a2); PRRAn(3,s,t3,a3); \
- PRRAn(4,s,t4,a4); PRRAn(5,s,t5,a5); PRRAn(6,s,t6,a6); \
- }
-
-#define PRE_MEM_READ(zzname, zzaddr, zzlen) \
- VG_TRACK( pre_mem_read, Vg_CoreSysCall, tid, zzname, zzaddr, zzlen)
-
-#define PRE_MEM_RASCIIZ(zzname, zzaddr) \
- VG_TRACK( pre_mem_read_asciiz, Vg_CoreSysCall, tid, zzname, zzaddr)
-
-#define PRE_MEM_WRITE(zzname, zzaddr, zzlen) \
- VG_TRACK( pre_mem_write, Vg_CoreSysCall, tid, zzname, zzaddr, zzlen)
-
-#define POST_MEM_WRITE(zzaddr, zzlen) \
- VG_TRACK( post_mem_write, Vg_CoreSysCall, tid, zzaddr, zzlen)
-
-
-//////////////////////////////////////////////////////////
-
-#define TId ThreadId
-#define UW UWord
-
-extern void VG_(generic_PRE_sys_socketpair) ( TId, UW, UW, UW, UW );
-extern UWord VG_(generic_POST_sys_socketpair) ( TId, UW, UW, UW, UW, UW );
-extern UWord VG_(generic_POST_sys_socket) ( TId, UW );
-extern void VG_(generic_PRE_sys_bind) ( TId, UW, UW, UW );
-extern void VG_(generic_PRE_sys_accept) ( TId, UW, UW, UW );
-extern UWord VG_(generic_POST_sys_accept) ( TId, UW, UW, UW, UW );
-extern void VG_(generic_PRE_sys_sendto) ( TId, UW, UW, UW, UW, UW, UW );
-extern void VG_(generic_PRE_sys_send) ( TId, UW, UW, UW );
-extern void VG_(generic_PRE_sys_recvfrom) ( TId, UW, UW, UW, UW, UW, UW );
-extern void VG_(generic_POST_sys_recvfrom) ( TId, UW, UW, UW, UW, UW, UW, UW );
-extern void VG_(generic_PRE_sys_recv) ( TId, UW, UW, UW );
-extern void VG_(generic_POST_sys_recv) ( TId, UW, UW, UW, UW );
-extern void VG_(generic_PRE_sys_connect) ( TId, UW, UW, UW );
-extern void VG_(generic_PRE_sys_setsockopt) ( TId, UW, UW, UW, UW, UW );
-extern void VG_(generic_PRE_sys_getsockopt) ( TId, UW, UW, UW, UW, UW );
-extern void VG_(generic_POST_sys_getsockopt) ( TId, UW, UW, UW, UW, UW, UW );
-extern void VG_(generic_PRE_sys_getsockname) ( TId, UW, UW, UW );
-extern void VG_(generic_POST_sys_getsockname) ( TId, UW, UW, UW, UW );
-extern void VG_(generic_PRE_sys_getpeername) ( TId, UW, UW, UW );
-extern void VG_(generic_POST_sys_getpeername) ( TId, UW, UW, UW, UW );
-extern void VG_(generic_PRE_sys_sendmsg) ( TId, UW, UW );
-extern void VG_(generic_PRE_sys_recvmsg) ( TId, UW, UW );
-extern void VG_(generic_POST_sys_recvmsg) ( TId, UW, UW, UW );
-
-extern void VG_(generic_PRE_sys_semop) ( TId, UW, UW, UW );
-extern void VG_(generic_PRE_sys_semtimedop) ( TId, UW, UW, UW, UW );
-extern void VG_(generic_PRE_sys_semctl) ( TId, UW, UW, UW, UW );
-extern void VG_(generic_POST_sys_semctl) ( TId, UW, UW, UW, UW, UW );
-extern void VG_(generic_PRE_sys_msgsnd) ( TId, UW, UW, UW, UW );
-extern void VG_(generic_PRE_sys_msgrcv) ( TId, UW, UW, UW, UW, UW );
-extern void VG_(generic_POST_sys_msgrcv) ( TId, UW, UW, UW, UW, UW, UW );
-extern void VG_(generic_PRE_sys_msgctl) ( TId, UW, UW, UW );
-extern void VG_(generic_POST_sys_msgctl) ( TId, UW, UW, UW, UW );
-extern UWord VG_(generic_PRE_sys_shmat) ( TId, UW, UW, UW );
-extern void VG_(generic_POST_sys_shmat) ( TId, UW, UW, UW, UW );
-extern Bool VG_(generic_PRE_sys_shmdt) ( TId, UW );
-extern void VG_(generic_POST_sys_shmdt) ( TId, UW, UW );
-extern void VG_(generic_PRE_sys_shmctl) ( TId, UW, UW, UW );
-extern void VG_(generic_POST_sys_shmctl) ( TId, UW, UW, UW, UW );
-
-#undef TId
-#undef UW
-
-#endif // __PRIV_SYSCALLS_H
-
-/*--------------------------------------------------------------------*/
-/*--- end ---*/
-/*--------------------------------------------------------------------*/
-
diff --git a/coregrind/m_syscalls/priv_types_n_macros.h b/coregrind/m_syscalls/priv_types_n_macros.h
new file mode 100644
index 000000000..711f06164
--- /dev/null
+++ b/coregrind/m_syscalls/priv_types_n_macros.h
@@ -0,0 +1,348 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Types and macros for writing syscall wrappers. ---*/
+/*--- priv_syscalls.h ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2000-2005 Julian Seward
+ jseward@acm.org
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#ifndef __PRIV_TYPES_N_MACROS_H
+#define __PRIV_TYPES_N_MACROS_H
+
+/* requires #include "pub_core_options.h" */
+/* requires #include "pub_core_signals.h" */
+
+/* This header defines types and macros which are useful for writing
+ syscall wrappers. It does not give prototypes for any such
+ headers, though: that is the job of the priv_syscalls-*.h headers.
+ This header gets included in any file which defines or declares
+ wrappers, and as such should only contain stuff which is relevant
+ to all such files.
+*/
+
+/* ---------------------------------------------------------------------
+ Types that are used in syscall wrappers.
+ ------------------------------------------------------------------ */
+
+/* Arguments for a syscall. */
+typedef
+ struct {
+ UWord sysno;
+ UWord arg1;
+ UWord arg2;
+ UWord arg3;
+ UWord arg4;
+ UWord arg5;
+ UWord arg6;
+ }
+ SyscallArgs;
+
+/* Current status of a syscall being done on behalf of the client. */
+typedef
+ struct {
+ enum { SsSuccess=1, SsFailure, SsHandToKernel, SsIdle } what;
+ UWord val; /* only meaningful for .what == Success or Failure */
+ }
+ SyscallStatus;
+
+/* Guest state layout info for syscall args. */
+typedef
+ struct {
+ Int o_sysno;
+ Int o_arg1;
+ Int o_arg2;
+ Int o_arg3;
+ Int o_arg4;
+ Int o_arg5;
+ Int o_arg6;
+ Int o_retval;
+ }
+ SyscallArgLayout;
+
+/* Flags describing syscall wrappers */
+#define SfMayBlock (1 << 1) /* may block */
+#define SfPostOnFail (1 << 2) /* call POST() function on failure */
+/* #define SfPadAddr (1 << 3) */ /* pad+unpad address space around syscall */
+#define SfPollAfter (1 << 4) /* poll for signals on completion */
+#define SfYieldAfter (1 << 5) /* yield on completion */
+
+
+/* ---------------------------------------------------------------------
+ The syscall table.
+ ------------------------------------------------------------------ */
+
+typedef
+ struct {
+ void (*before) ( ThreadId,
+ SyscallArgLayout*,
+ /*MOD*/SyscallArgs*,
+ /*OUT*/SyscallStatus*,
+ /*OUT*/UWord*
+ );
+
+ void (*after) ( ThreadId,
+ SyscallArgs*,
+ SyscallStatus*
+ );
+ }
+ SyscallTableEntry;
+
+/* Syscall table entries bind __NR_xxx syscall numbers to the PRE/POST
+ wrappers for the relevant syscall used in the OS kernel for that
+ number. Note that the constant names don't always match the
+ wrapper names in a straightforward way. For example, on x86/Linux:
+
+ __NR_lchown --> sys_lchown16()
+ __NR_lchown32 --> sys_lchown()
+ __NR_select --> old_select()
+ __NR__newselect --> sys_select()
+*/
+
+
+/* These are defined in the relevant platform-specific files --
+ syscalls-arch-os.c */
+
+extern const SyscallTableEntry VGP_(syscall_table)[];
+
+extern const UInt VGP_(syscall_table_size);
+
+
+/* ---------------------------------------------------------------------
+ Declaring and defining wrappers.
+ ------------------------------------------------------------------ */
+
+/* Templates for generating the PRE and POST macros -- that is, the
+ formal parameter lists for the definitions of wrapper functions.
+
+ Since these names exist in the global namespace, 'auxstr' should
+ give an auxiliary string, eg, "generic", "x86_linux", "linux", etc,
+ that ensures the names won't clash with other wrappers.
+
+ You should create corresponding global declarations using
+ DECL_TEMPLATE (indirectly) below.
+*/
+
+#define DEFN_PRE_TEMPLATE(auxstr, name) \
+ void vgSysWrap_##auxstr##_##name##_before \
+ ( ThreadId tid, \
+ SyscallArgLayout* layout, \
+ /*MOD*/SyscallArgs* args, \
+ /*OUT*/SyscallStatus* status, \
+ /*OUT*/UWord* flags \
+ )
+
+#define DEFN_POST_TEMPLATE(auxstr, name) \
+ void vgSysWrap_##auxstr##_##name##_after \
+ ( ThreadId tid, \
+ SyscallArgs* args, \
+ SyscallStatus* status \
+ )
+
+
+/* This macro generates declarations (prototypes) for wrappers. It
+ declares both the pre-wrapper and the post-wrapper, even though the
+ post-wrapper may not actually exist.
+*/
+#define DECL_TEMPLATE(auxstr, name) \
+ extern \
+ void vgSysWrap_##auxstr##_##name##_before \
+ ( ThreadId tid, \
+ SyscallArgLayout* layout, \
+ /*MOD*/SyscallArgs* args, \
+ /*OUT*/SyscallStatus* status, \
+ /*OUT*/UWord* flags \
+ ); \
+ extern \
+ void vgSysWrap_##auxstr##_##name##_after \
+ ( ThreadId tid, \
+ SyscallArgs* args, \
+ SyscallStatus* status \
+ );
+
+
+
+/* Macros for conveniently generating entries in the syscall
+ tables. This first pair are not used directly. */
+
+#define WRAPPER_ENTRY_X_(auxstr, sysno, name) \
+ [sysno] = { vgSysWrap_##auxstr##_##name##_before, NULL }
+#define WRAPPER_ENTRY_XY(auxstr, sysno, name) \
+ [sysno] = { vgSysWrap_##auxstr##_##name##_before, \
+ vgSysWrap_##auxstr##_##name##_after }
+
+/* Add a generic wrapper to a syscall table. */
+#define GENX_(sysno, name) WRAPPER_ENTRY_X_(generic, sysno, name)
+#define GENXY(sysno, name) WRAPPER_ENTRY_XY(generic, sysno, name)
+
+/* Add a Linux-specific, arch-independent wrapper to a syscall
+ table. */
+#define LINX_(sysno, name) WRAPPER_ENTRY_X_(linux, sysno, name)
+#define LINXY(sysno, name) WRAPPER_ENTRY_XY(linux, sysno, name)
+
+
+
+/* ---------------------------------------------------------------------
+ Macros useful for writing wrappers concisely. These refer to the
+ parameters declared by DEFN_{PRE,POST}_TEMPLATE and so in a way do
+ not help clarity of understanding. But they are just too useful to
+ omit.
+ ------------------------------------------------------------------ */
+
+/* Reference to the syscall's arguments -- the ones which the
+ pre-wrapper may have modified, not the original copy. */
+#define SYSNO (args->sysno)
+#define ARG1 (args->arg1)
+#define ARG2 (args->arg2)
+#define ARG3 (args->arg3)
+#define ARG4 (args->arg4)
+#define ARG5 (args->arg5)
+#define ARG6 (args->arg6)
+
+/* Reference to the syscall's current result status/value. Note that
+
+ (1) status->val by itself is meaningless -- you have to consider it
+ together with status->what, which is why RES uses a helper
+ function (this also has the desirable effect of turning RES
+ into a non-lvalue).
+
+ (2) post-wrappers will not get called in case of failure (unless
+ PostOnFail is set, which is rare). This is why the assertion
+ in getRES is viable.
+
+ If you really really want to just get hold of status->val without
+ inspecting status->what, use RES_unchecked. This is dangerous and
+ therefore discouraged.
+*/
+#define SUCCESS (status->what == SsSuccess)
+#define FAILURE (status->what == SsFailure)
+#define SWHAT (status->what)
+#define RES_unchecked (status->val) /* do not use! */
+#define RES (getRES(status)) /* use this instead, if possible */
+
+static inline UWord getRES ( SyscallStatus* st ) {
+ vg_assert(st->what == SsSuccess);
+ return st->val;
+}
+
+
+/* Set the current result status/value in various ways. */
+#define SET_STATUS_Success(zzz) \
+ do { status->what = SsSuccess; \
+ status->val = (zzz); \
+ } while (0)
+
+#define SET_STATUS_Failure(zzz) \
+ do { Word wzz = (Word)(zzz); \
+ /* Catch out wildly bogus error values. */ \
+ vg_assert(wzz >= 0 && wzz < 10000); \
+ status->what = SsFailure; \
+ status->val = wzz; \
+ } while (0)
+
+#define SET_STATUS_from_SysRes(zzz) \
+ do { \
+ SysRes zres = (zzz); \
+ if (zres.isError) { \
+ SET_STATUS_Failure(zres.val); \
+ } else { \
+ SET_STATUS_Success(zres.val); \
+ } \
+ } while (0)
+
+#define PRINT(format, args...) \
+ if (VG_(clo_trace_syscalls)) \
+ VG_(printf)(format, ## args)
+
+
+/* Macros used to tell tools about uses of scalar arguments. Note,
+ these assume little-endianness. These can only be used in
+ pre-wrappers, and they refer to the layout parameter passed in. */
+/* PRRAn == "pre-register-read-argument"
+ PRRSN == "pre-register-read-syscall"
+*/
+
+#define PRRSN \
+ VG_(tdict).track_pre_reg_read(Vg_CoreSysCall, tid, "(syscallno)", \
+ layout->o_sysno, sizeof(UWord));
+#define PRRAn(n,s,t,a) \
+ VG_(tdict).track_pre_reg_read(Vg_CoreSysCall, tid, s"("#a")", \
+ layout->o_arg##n, sizeof(t));
+#define PRE_REG_READ0(tr, s) \
+ if (VG_(tdict).track_pre_reg_read) { \
+ PRRSN; \
+ }
+#define PRE_REG_READ1(tr, s, t1, a1) \
+ if (VG_(tdict).track_pre_reg_read) { \
+ PRRSN; \
+ PRRAn(1,s,t1,a1); \
+ }
+#define PRE_REG_READ2(tr, s, t1, a1, t2, a2) \
+ if (VG_(tdict).track_pre_reg_read) { \
+ PRRSN; \
+ PRRAn(1,s,t1,a1); PRRAn(2,s,t2,a2); \
+ }
+#define PRE_REG_READ3(tr, s, t1, a1, t2, a2, t3, a3) \
+ if (VG_(tdict).track_pre_reg_read) { \
+ PRRSN; \
+ PRRAn(1,s,t1,a1); PRRAn(2,s,t2,a2); PRRAn(3,s,t3,a3); \
+ }
+#define PRE_REG_READ4(tr, s, t1, a1, t2, a2, t3, a3, t4, a4) \
+ if (VG_(tdict).track_pre_reg_read) { \
+ PRRSN; \
+ PRRAn(1,s,t1,a1); PRRAn(2,s,t2,a2); PRRAn(3,s,t3,a3); \
+ PRRAn(4,s,t4,a4); \
+ }
+#define PRE_REG_READ5(tr, s, t1, a1, t2, a2, t3, a3, t4, a4, t5, a5) \
+ if (VG_(tdict).track_pre_reg_read) { \
+ PRRSN; \
+ PRRAn(1,s,t1,a1); PRRAn(2,s,t2,a2); PRRAn(3,s,t3,a3); \
+ PRRAn(4,s,t4,a4); PRRAn(5,s,t5,a5); \
+ }
+#define PRE_REG_READ6(tr, s, t1, a1, t2, a2, t3, a3, t4, a4, t5, a5, t6, a6) \
+ if (VG_(tdict).track_pre_reg_read) { \
+ PRRSN; \
+ PRRAn(1,s,t1,a1); PRRAn(2,s,t2,a2); PRRAn(3,s,t3,a3); \
+ PRRAn(4,s,t4,a4); PRRAn(5,s,t5,a5); PRRAn(6,s,t6,a6); \
+ }
+
+#define PRE_MEM_READ(zzname, zzaddr, zzlen) \
+ VG_TRACK( pre_mem_read, Vg_CoreSysCall, tid, zzname, zzaddr, zzlen)
+
+#define PRE_MEM_RASCIIZ(zzname, zzaddr) \
+ VG_TRACK( pre_mem_read_asciiz, Vg_CoreSysCall, tid, zzname, zzaddr)
+
+#define PRE_MEM_WRITE(zzname, zzaddr, zzlen) \
+ VG_TRACK( pre_mem_write, Vg_CoreSysCall, tid, zzname, zzaddr, zzlen)
+
+#define POST_MEM_WRITE(zzaddr, zzlen) \
+ VG_TRACK( post_mem_write, Vg_CoreSysCall, tid, zzaddr, zzlen)
+
+
+#endif // __PRIV_TYPES_N_MACROS_H
+
+/*--------------------------------------------------------------------*/
+/*--- end priv_types_n_macros.h ---*/
+/*--------------------------------------------------------------------*/
diff --git a/coregrind/m_syscalls/syscall-x86-linux.S b/coregrind/m_syscalls/syscall-x86-linux.S
index ea4547223..5e403b0a3 100644
--- a/coregrind/m_syscalls/syscall-x86-linux.S
+++ b/coregrind/m_syscalls/syscall-x86-linux.S
@@ -32,104 +32,6 @@
#include "vki_unistd.h"
#include "libvex_guest_offsets.h"
-.globl VG_(do_syscall)
-
-/*
- Perform a Linux syscall with int 0x80
-
- Syscall args are passed on the stack
- Int VG_(do_syscall)(Int syscall_no, UWord a1, UWord a2, UWord a3,
- UWord a4, UWord a5, UWord a6)
-
- This has no effect on the virtual machine; the assumption is
- that the syscall mechanism makes no useful changes to any
- register except %eax, which is returned. (Some kernels will
- change other registers randomly, but they're just compiler
- spill values.)
- */
-VG_(do_syscall):
- push %esi
- push %edi
- push %ebx
- push %ebp
- movl 16+ 4(%esp),%eax
- movl 16+ 8(%esp),%ebx
- movl 16+12(%esp),%ecx
- movl 16+16(%esp),%edx
- movl 16+20(%esp),%esi
- movl 16+24(%esp),%edi
- movl 16+28(%esp),%ebp
- int $0x80
- popl %ebp
- popl %ebx
- popl %edi
- popl %esi
- ret
-
-/*
- Perform a clone system call. clone is strange because it has
- fork()-like return-twice semantics, so it needs special
- handling here.
-
- Upon entry, we have:
-
- int (fn)(void*) in 0+FSZ(%esp)
- void* child_stack in 4+FSZ(%esp)
- int flags in 8+FSZ(%esp)
- void* arg in 12+FSZ(%esp)
- pid_t* child_tid in 16+FSZ(%esp)
- pid_t* parent_tid in 20+FSZ(%esp)
- void* tls_ptr in 24+FSZ(%esp)
-
- System call requires:
-
- int $__NR_clone in %eax
- int flags in %ebx
- void* child_stack in %ecx
- pid_t* parent_tid in %edx
- pid_t* child_tid in %edi
- void* tls_ptr in %esi
- */
-.globl VG_(clone)
-VG_(clone):
-#define FSZ (4+4+4) /* frame size = retaddr+ebx+edi */
- push %ebx
- push %edi
- /* set up child stack with function and arg */
- movl 4+FSZ(%esp), %ecx /* syscall arg2: child stack */
- movl 12+FSZ(%esp), %ebx /* fn arg */
- movl 0+FSZ(%esp), %eax /* fn */
- lea -8(%ecx), %ecx /* make space on stack */
- movl %ebx, 4(%ecx) /* fn arg */
- movl %eax, 0(%ecx) /* fn */
-
- /* get other args to clone */
- movl 8+FSZ(%esp), %ebx /* syscall arg1: flags */
- movl 20+FSZ(%esp), %edx /* syscall arg3: parent tid * */
- movl 16+FSZ(%esp), %edi /* syscall arg4: child tid * */
- movl 24+FSZ(%esp), %esi /* syscall arg5: tls_ptr * */
- movl $__NR_clone, %eax
- int $0x80 /* clone() */
- testl %eax, %eax /* child if retval == 0 */
- jnz 1f
-
- /* CHILD - call thread function */
- popl %eax
- call *%eax /* call fn */
-
- /* exit with result */
- movl %eax, %ebx /* arg1: return value from fn */
- movl $__NR_exit, %eax
- int $0x80
-
- /* Hm, exit returned */
- ud2
-
-1: /* PARENT or ERROR */
- pop %edi
- pop %ebx
- ret
-#undef FSZ
.globl VG_(sigreturn)
VG_(sigreturn):
@@ -163,7 +65,8 @@ VG_(sigreturn):
Prototype:
- Int VGA_(_client_syscall)(Int syscallno, // 0
+ Int VGA_(do_syscall_for_client_WRK)(
+ Int syscallno, // 0
void* guest_state, // 4
const vki_sigset_t *sysmask, // 8
const vki_sigset_t *postmask, // 12
@@ -174,8 +77,8 @@ VG_(sigreturn):
/* from vki_arch.h */
#define VKI_SIG_SETMASK 2
-.globl VGA_(_client_syscall)
-VGA_(_client_syscall):
+.globl VGA_(do_syscall_for_client_WRK)
+VGA_(do_syscall_for_client_WRK):
/* save callee-saved regs */
push %esi
push %edi
@@ -234,8 +137,9 @@ VGA_(_client_syscall):
ret
.section .rodata
-/* export the ranges so that VGA_(interrupted_syscall) can do the
- right thing */
+/* export the ranges so that
+ VG_(fixup_guest_state_after_syscall_interrupted) can do the
+ right thing */
.globl VGA_(blksys_setup)
.globl VGA_(blksys_restart)
diff --git a/coregrind/m_syscalls/syscalls-amd64-linux.c b/coregrind/m_syscalls/syscalls-amd64-linux.c
index 355034b5f..62b15dcdd 100644
--- a/coregrind/m_syscalls/syscalls-amd64-linux.c
+++ b/coregrind/m_syscalls/syscalls-amd64-linux.c
@@ -609,7 +609,7 @@ PRE(sys_clone, Special)
/* Thread creation was successful; let the child have the chance
to run */
- VG_(vg_yield)();
+ XXX FIXME VG_(vg_yield)();
}
}
@@ -628,7 +628,7 @@ PRE(sys_rt_sigreturn, Special)
VG_(sigframe_destroy)(tid, True);
/* Keep looking for signals until there are none */
- VG_(poll_signals)(tid);
+ XXX FIXME VG_(poll_signals)(tid);
/* placate return-must-be-set assertion */
SET_RESULT(RES);
diff --git a/coregrind/m_syscalls/syscalls.c b/coregrind/m_syscalls/syscalls-generic.c
index faa6514a0..e473ed94b 100644
--- a/coregrind/m_syscalls/syscalls.c
+++ b/coregrind/m_syscalls/syscalls-generic.c
@@ -1,6 +1,6 @@
/*--------------------------------------------------------------------*/
-/*--- Handle system calls. syscalls.c ---*/
+/*--- Wrappers for generic Unix system calls syscalls-generic.c ---*/
/*--------------------------------------------------------------------*/
/*
@@ -32,91 +32,21 @@
#include "pub_core_debuglog.h"
#include "pub_core_aspacemgr.h"
#include "pub_core_libcbase.h"
-#include "pub_core_libcassert.h"
-#include "pub_core_libcfile.h"
#include "pub_core_libcprint.h"
+#include "pub_core_libcfile.h"
+#include "pub_core_libcassert.h"
#include "pub_core_main.h"
-#include "pub_core_profile.h"
#include "pub_core_stacktrace.h"
-#include "pub_core_syscalls.h"
#include "pub_core_tooliface.h"
-#include "priv_syscalls.h"
-
-
-/* All system calls are channelled through here, doing two things:
-
- * notify the tool of the events (mem/reg reads, writes) happening
-
- * perform the syscall, usually by passing it along to the kernel
- unmodified.
-
- A magical piece of assembly code, VG_(do_syscall)(), in syscall-$PLATFORM.S
- does the tricky bit of passing a syscall to the kernel, whilst
- having the simulator retain control.
-*/
-
-/* ---------------------------------------------------------------------
- A simple atfork() facility for Valgrind's internal use
- ------------------------------------------------------------------ */
-
-struct atfork {
- vg_atfork_t pre;
- vg_atfork_t parent;
- vg_atfork_t child;
-};
-
-#define VG_MAX_ATFORK 10
-
-static struct atfork atforks[VG_MAX_ATFORK];
-static Int n_atfork;
-
-void VG_(atfork)(vg_atfork_t pre, vg_atfork_t parent, vg_atfork_t child)
-{
- Int i;
-
- for(i = 0; i < n_atfork; i++) {
- if (atforks[i].pre == pre &&
- atforks[i].parent == parent &&
- atforks[i].child == child)
- return;
- }
-
- if (n_atfork >= VG_MAX_ATFORK)
- VG_(core_panic)("Too many VG_(atfork) handlers requested: raise VG_MAX_ATFORK");
-
- atforks[n_atfork].pre = pre;
- atforks[n_atfork].parent = parent;
- atforks[n_atfork].child = child;
-
- n_atfork++;
-}
-
-void VG_(do_atfork_pre)(ThreadId tid)
-{
- Int i;
-
- for(i = 0; i < n_atfork; i++)
- if (atforks[i].pre != NULL)
- (*atforks[i].pre)(tid);
-}
-
-void VG_(do_atfork_parent)(ThreadId tid)
-{
- Int i;
+#include "pub_core_options.h"
+#include "pub_core_signals.h"
+#include "pub_core_syscalls.h"
- for(i = 0; i < n_atfork; i++)
- if (atforks[i].parent != NULL)
- (*atforks[i].parent)(tid);
-}
+#include "priv_types_n_macros.h"
+#include "priv_syscalls-generic.h"
-void VG_(do_atfork_child)(ThreadId tid)
-{
- Int i;
+#include "vki_unistd.h" /* for the __NR_* constants */
- for(i = 0; i < n_atfork; i++)
- if (atforks[i].child != NULL)
- (*atforks[i].child)(tid);
-}
/* return true if address range entirely contained within client
address space */
@@ -143,8 +73,9 @@ Bool VG_(valid_client_addr)(Addr start, SizeT size, ThreadId tid,
syscallname, start, end, cl_base, VG_(client_end), ret);
if (!ret && syscallname != NULL) {
- VG_(message)(Vg_UserMsg, "Warning: client syscall %s tried to modify addresses %p-%p",
- syscallname, start, end);
+ VG_(message)(Vg_UserMsg, "Warning: client syscall %s tried "
+ "to modify addresses %p-%p",
+ syscallname, start, end);
if (VG_(clo_verbosity) > 1) {
VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
@@ -181,8 +112,8 @@ void mash_addr_and_len( Addr* a, SizeT* len)
*a = ra;
}
-static
-void mmap_segment ( Addr a, SizeT len, UInt prot, UInt mm_flags, Int fd, ULong offset )
+void VG_(mmap_segment) ( Addr a, SizeT len, UInt prot,
+ UInt mm_flags, Int fd, ULong offset )
{
Bool rr, ww, xx;
UInt flags;
@@ -207,21 +138,21 @@ void mmap_segment ( Addr a, SizeT len, UInt prot, UInt mm_flags, Int fd, ULong o
}
static
-Addr mremap_segment ( Addr old_addr, SizeT old_size,
- Addr new_addr, SizeT new_size,
- UInt flags, ThreadId tid)
+SysRes mremap_segment ( Addr old_addr, SizeT old_size,
+ Addr new_addr, SizeT new_size,
+ UInt flags, ThreadId tid)
{
- Addr ret;
+ SysRes ret;
Segment *seg, *next;
old_size = VG_PGROUNDUP(old_size);
new_size = VG_PGROUNDUP(new_size);
if (VG_PGROUNDDN(old_addr) != old_addr)
- return -VKI_EINVAL;
+ return VG_(mk_SysRes_Error)( VKI_EINVAL );
if (!VG_(valid_client_addr)(old_addr, old_size, tid, "mremap(old_addr)"))
- return -VKI_EFAULT;
+ return VG_(mk_SysRes_Error)( VKI_EFAULT );
/* fixed at the current address means we don't move it */
if ((flags & VKI_MREMAP_FIXED) && (old_addr == new_addr))
@@ -229,28 +160,28 @@ Addr mremap_segment ( Addr old_addr, SizeT old_size,
if (flags & VKI_MREMAP_FIXED) {
if (VG_PGROUNDDN(new_addr) != new_addr)
- return -VKI_EINVAL;
+ return VG_(mk_SysRes_Error)( VKI_EINVAL );
if (!VG_(valid_client_addr)(new_addr, new_size, tid, "mremap(new_addr)"))
- return -VKI_ENOMEM;
+ return VG_(mk_SysRes_Error)( VKI_ENOMEM );
/* check for overlaps */
if ((old_addr < (new_addr+new_size) &&
(old_addr+old_size) > new_addr) ||
(new_addr < (old_addr+new_size) &&
(new_addr+new_size) > old_addr))
- return -VKI_EINVAL;
+ return VG_(mk_SysRes_Error)( VKI_EINVAL );
}
/* Do nothing */
if (!(flags & VKI_MREMAP_FIXED) && new_size == old_size)
- return old_addr;
+ return VG_(mk_SysRes_Success)( old_addr );
seg = VG_(find_segment)(old_addr);
/* range must be contained within segment */
if (seg == NULL || !VG_(seg_contains)(seg, old_addr, old_size))
- return -VKI_EINVAL;
+ return VG_(mk_SysRes_Error)( VKI_EINVAL );
next = VG_(find_segment_above_mapped)(old_addr);
@@ -264,7 +195,8 @@ Addr mremap_segment ( Addr old_addr, SizeT old_size,
Addr a;
if ((flags & (VKI_MREMAP_FIXED|VKI_MREMAP_MAYMOVE)) == 0)
- return -VKI_ENOMEM; /* not allowed to move */
+ /* not allowed to move */
+ return VG_(mk_SysRes_Error)( VKI_ENOMEM );
if ((flags & VKI_MREMAP_FIXED) == 0)
new_addr = 0;
@@ -272,19 +204,18 @@ Addr mremap_segment ( Addr old_addr, SizeT old_size,
a = VG_(find_map_space)(new_addr, new_size, True);
if ((flags & VKI_MREMAP_FIXED) && a != new_addr)
- return -VKI_ENOMEM; /* didn't find the place we wanted */
+ /* didn't find the place we wanted */
+ return VG_(mk_SysRes_Error)( VKI_ENOMEM );
new_addr = a;
- ret = a;
/* we've nailed down the location */
- flags |= VKI_MREMAP_FIXED|VKI_MREMAP_MAYMOVE;
+ flags |= VKI_MREMAP_FIXED|VKI_MREMAP_MAYMOVE;
ret = VG_(do_syscall5)(__NR_mremap, old_addr, old_size, new_size,
flags, new_addr);
- if (ret != new_addr) {
- vg_assert(VG_(is_kerror)(ret));
+ if (ret.isError) {
return ret;
}
@@ -307,7 +238,7 @@ Addr mremap_segment ( Addr old_addr, SizeT old_size,
VG_(munmap)((void *)old_addr, old_size);
} else {
/* staying in place */
- ret = old_addr;
+ ret = VG_(mk_SysRes_Success)( old_addr );
if (new_size < old_size) {
VG_TRACK(die_mem_munmap, old_addr+new_size, old_size-new_size);
@@ -323,7 +254,7 @@ Addr mremap_segment ( Addr old_addr, SizeT old_size,
ret = VG_(do_syscall5)(__NR_mremap, old_addr, old_size, new_size,
flags, 0);
- if (ret != old_addr)
+ if (ret.isError || (!ret.isError && ret.val != old_addr))
return ret;
VG_TRACK(new_mem_mmap, old_addr+old_size, new_size-old_size,
@@ -343,34 +274,9 @@ Addr mremap_segment ( Addr old_addr, SizeT old_size,
}
-/* Is this a Linux kernel error return value? */
-/* From:
- http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/sysdeps/unix/sysv/
- linux/i386/sysdep.h?
- rev=1.28&content-type=text/x-cvsweb-markup&cvsroot=glibc
-
- \begin{quote}:
-
- Linux uses a negative return value to indicate syscall errors,
- unlike most Unices, which use the condition codes' carry flag.
-
- Since version 2.1 the return value of a system call might be
- negative even if the call succeeded. E.g., the 'lseek' system call
- might return a large offset. Therefore we must not anymore test
- for < 0, but test for a real error by making sure the value in %eax
- is a real error number. Linus said he will make sure the no syscall
- returns a value in -1 .. -4095 as a valid result so we can safely
- test with -4095.
-
- END QUOTE
-*/
-Bool VG_(is_kerror) ( Word res )
-{
- if (res >= -4095 && res <= -1)
- return True;
- else
- return False;
-}
+/* ---------------------------------------------------------------------
+ File-descriptor tracking
+ ------------------------------------------------------------------ */
/* One of these is allocated for each open file descriptor. */
@@ -527,11 +433,9 @@ Char *inet2name(struct vki_sockaddr_in *sa, UInt len, Char *name)
return name;
}
-
/*
* Try get some details about a socket.
*/
-
static void
getsockdetails(int fd)
{
@@ -773,8 +677,8 @@ static void check_cmsg_for_fds(ThreadId tid, struct vki_msghdr *msg)
static
void pre_mem_read_sockaddr ( ThreadId tid,
- Char *description,
- struct vki_sockaddr *sa, UInt salen )
+ Char *description,
+ struct vki_sockaddr *sa, UInt salen )
{
Char *outmsg;
@@ -858,11 +762,10 @@ void buf_and_len_pre_check( ThreadId tid, Addr buf_p, Addr buflen_p,
}
static
-void buf_and_len_post_check( ThreadId tid, Int res,
+void buf_and_len_post_check( ThreadId tid, SysRes res,
Addr buf_p, Addr buflen_p, Char* s )
{
- if (!VG_(is_kerror)(res) && VG_(tdict).track_post_mem_write)
- {
+ if (!res.isError && VG_(tdict).track_post_mem_write) {
UInt buflen_out = deref_UInt( tid, buflen_p, s);
if (buflen_out > 0 && buf_p != (Addr)NULL) {
VG_(tdict).track_post_mem_write( Vg_CoreSysCall, tid, buf_p, buflen_out );
@@ -1001,13 +904,14 @@ VG_(generic_PRE_sys_socketpair) ( ThreadId tid,
arg3, 2*sizeof(int) );
}
-UWord
+SysRes
VG_(generic_POST_sys_socketpair) ( ThreadId tid,
- UWord res,
+ SysRes res,
UWord arg0, UWord arg1,
UWord arg2, UWord arg3 )
{
- UWord r = res;
+ SysRes r = res;
+ vg_assert(!res.isError); /* guaranteed by caller */
Int fd1 = ((Int*)arg3)[0];
Int fd2 = ((Int*)arg3)[1];
POST_MEM_WRITE( arg3, 2*sizeof(int) );
@@ -1015,7 +919,7 @@ VG_(generic_POST_sys_socketpair) ( ThreadId tid,
!VG_(fd_allowed)(fd2, "socketcall.socketpair", tid, True)) {
VG_(close)(fd1);
VG_(close)(fd2);
- r = -VKI_EMFILE;
+ r = VG_(mk_SysRes_Error)( VKI_EMFILE );
} else {
POST_MEM_WRITE( arg3, 2*sizeof(int) );
if (VG_(clo_track_fds)) {
@@ -1028,16 +932,17 @@ VG_(generic_POST_sys_socketpair) ( ThreadId tid,
/* ------ */
-UWord
-VG_(generic_POST_sys_socket) ( ThreadId tid, UWord res )
+SysRes
+VG_(generic_POST_sys_socket) ( ThreadId tid, SysRes res )
{
- UWord r = res;
- if (!VG_(fd_allowed)(res, "socket", tid, True)) {
- VG_(close)(res);
- r = -VKI_EMFILE;
+ SysRes r = res;
+ vg_assert(!res.isError); /* guaranteed by caller */
+ if (!VG_(fd_allowed)(res.val, "socket", tid, True)) {
+ VG_(close)(res.val);
+ r = VG_(mk_SysRes_Error)( VKI_EMFILE );
} else {
if (VG_(clo_track_fds))
- VG_(record_fd_open)(tid, res, NULL);
+ VG_(record_fd_open)(tid, res.val, NULL);
}
return r;
}
@@ -1071,15 +976,16 @@ VG_(generic_PRE_sys_accept) ( ThreadId tid,
"socketcall.accept(addrlen_in)" );
}
-UWord
+SysRes
VG_(generic_POST_sys_accept) ( ThreadId tid,
- UWord res,
+ SysRes res,
UWord arg0, UWord arg1, UWord arg2 )
{
- UWord r = res;
- if (!VG_(fd_allowed)(res, "accept", tid, True)) {
- VG_(close)(res);
- r = -VKI_EMFILE;
+ SysRes r = res;
+ vg_assert(!res.isError); /* guaranteed by caller */
+ if (!VG_(fd_allowed)(res.val, "accept", tid, True)) {
+ VG_(close)(res.val);
+ r = VG_(mk_SysRes_Error)( VKI_EMFILE );
} else {
Addr addr_p = arg1;
Addr addrlen_p = arg2;
@@ -1087,7 +993,7 @@ VG_(generic_POST_sys_accept) ( ThreadId tid,
buf_and_len_post_check ( tid, res, addr_p, addrlen_p,
"socketcall.accept(addrlen_out)" );
if (VG_(clo_track_fds))
- VG_(record_fd_open)(tid, res, NULL);
+ VG_(record_fd_open)(tid, res.val, NULL);
}
return r;
}
@@ -1146,7 +1052,7 @@ VG_(generic_PRE_sys_recvfrom) ( ThreadId tid,
void
VG_(generic_POST_sys_recvfrom) ( ThreadId tid,
- UWord res,
+ SysRes res,
UWord arg0, UWord arg1, UWord arg2,
UWord arg3, UWord arg4, UWord arg5 )
{
@@ -1155,6 +1061,7 @@ VG_(generic_POST_sys_recvfrom) ( ThreadId tid,
Addr from_p = arg4;
Addr fromlen_p = arg5;
+ vg_assert(!res.isError); /* guaranteed by caller */
if (from_p != (Addr)NULL)
buf_and_len_post_check ( tid, res, from_p, fromlen_p,
"socketcall.recvfrom(fromlen_out)" );
@@ -1239,12 +1146,13 @@ VG_(generic_PRE_sys_getsockopt) ( ThreadId tid,
void
VG_(generic_POST_sys_getsockopt) ( ThreadId tid,
- UWord res,
+ SysRes res,
UWord arg0, UWord arg1, UWord arg2,
UWord arg3, UWord arg4 )
{
Addr optval_p = arg3;
Addr optlen_p = arg4;
+ vg_assert(!res.isError); /* guaranteed by caller */
if (optval_p != (Addr)NULL)
buf_and_len_post_check ( tid, res, optval_p, optlen_p,
"socketcall.getsockopt(optlen_out)" );
@@ -1267,11 +1175,12 @@ VG_(generic_PRE_sys_getsockname) ( ThreadId tid,
void
VG_(generic_POST_sys_getsockname) ( ThreadId tid,
- UWord res,
+ SysRes res,
UWord arg0, UWord arg1, UWord arg2 )
{
Addr name_p = arg1;
Addr namelen_p = arg2;
+ vg_assert(!res.isError); /* guaranteed by caller */
buf_and_len_post_check ( tid, res, name_p, namelen_p,
"socketcall.getsockname(namelen_out)" );
}
@@ -1293,11 +1202,12 @@ VG_(generic_PRE_sys_getpeername) ( ThreadId tid,
void
VG_(generic_POST_sys_getpeername) ( ThreadId tid,
- UWord res,
+ SysRes res,
UWord arg0, UWord arg1, UWord arg2 )
{
Addr name_p = arg1;
Addr namelen_p = arg2;
+ vg_assert(!res.isError); /* guaranteed by caller */
buf_and_len_post_check ( tid, res, name_p, namelen_p,
"socketcall.getpeername(namelen_out)" );
}
@@ -1326,7 +1236,6 @@ VG_(generic_PRE_sys_recvmsg) ( ThreadId tid,
void
VG_(generic_POST_sys_recvmsg) ( ThreadId tid,
- UWord res,
UWord arg0, UWord arg1 )
{
struct vki_msghdr *msg = (struct vki_msghdr *)arg1;
@@ -1368,22 +1277,22 @@ VG_(generic_PRE_sys_semtimedop) ( ThreadId tid,
static
UInt get_sem_count( Int semid )
{
- struct vki_semid_ds buf;
- union vki_semun arg;
- long res;
+ struct vki_semid_ds buf;
+ union vki_semun arg;
+ SysRes res;
- arg.buf = &buf;
+ arg.buf = &buf;
-#ifdef __NR_semctl
- res = VG_(do_syscall4)(__NR_semctl, semid, 0, VKI_IPC_STAT, *(UWord *)&arg);
-#else
- res = VG_(do_syscall5)(__NR_ipc, 3 /* IPCOP_semctl */, semid, 0,
- VKI_IPC_STAT, (UWord)&arg);
-#endif
- if ( VG_(is_kerror)(res) )
- return 0;
+# ifdef __NR_semctl
+ res = VG_(do_syscall4)(__NR_semctl, semid, 0, VKI_IPC_STAT, *(UWord *)&arg);
+# else
+ res = VG_(do_syscall5)(__NR_ipc, 3 /* IPCOP_semctl */, semid, 0,
+ VKI_IPC_STAT, (UWord)&arg);
+# endif
+ if (res.isError)
+ return 0;
- return buf.sem_nsems;
+ return buf.sem_nsems;
}
void
@@ -1568,15 +1477,15 @@ VG_(generic_POST_sys_msgctl) ( ThreadId tid,
static
UInt get_shm_size ( Int shmid )
{
-#ifdef __NR_shmctl
+# ifdef __NR_shmctl
struct vki_shmid64_ds buf;
- long __res = VG_(do_syscall3)(__NR_shmctl, shmid, VKI_IPC_STAT, (UWord)&buf);
-#else
+ SysRes __res = VG_(do_syscall3)(__NR_shmctl, shmid, VKI_IPC_STAT, (UWord)&buf);
+# else
struct vki_shmid_ds buf;
- long __res = VG_(do_syscall5)(__NR_ipc, 24 /* IPCOP_shmctl */, shmid,
+ SysRes __res = VG_(do_syscall5)(__NR_ipc, 24 /* IPCOP_shmctl */, shmid,
VKI_IPC_STAT, 0, (UWord)&buf);
-#endif
- if ( VG_(is_kerror) ( __res ) )
+# endif
+ if (__res.isError)
return 0;
return buf.shm_segsz;
@@ -1736,94 +1645,94 @@ VG_(generic_POST_sys_shmctl) ( ThreadId tid,
XXX: some of these are arch-specific, and should be factored out.
*/
-#define PRE(name, f) PRE_TEMPLATE( , vgArch_gen, name, f)
-#define POST(name) POST_TEMPLATE( , vgArch_gen, name)
-
-// Combine two 32-bit values into a 64-bit value
-#define LOHI64(lo,hi) ( (lo) | ((ULong)(hi) << 32) )
+#define PRE(name) DEFN_PRE_TEMPLATE(generic, name)
+#define POST(name) DEFN_POST_TEMPLATE(generic, name)
-//PRE(sys_exit_group, Special)
-//{
-// VG_(core_panic)("syscall exit_group() not caught by the scheduler?!");
-//}
+//zz // Combine two 32-bit values into a 64-bit value
+//zz #define LOHI64(lo,hi) ( (lo) | ((ULong)(hi) << 32) )
+//zz
+//zz //PRE(sys_exit_group, Special)
+//zz //{
+//zz // VG_(core_panic)("syscall exit_group() not caught by the scheduler?!");
+//zz //}
-PRE(sys_exit, Special)
+PRE(sys_exit)
{
+ ThreadState* tst;
/* simple; just make this thread exit */
PRINT("exit( %d )", ARG1);
PRE_REG_READ1(void, "exit", int, exitcode);
+ tst = VG_(get_ThreadState)(tid);
+ /* Set the thread's status to be exiting, then claim that the
+ syscall succeeded. */
tst->exitreason = VgSrc_ExitSyscall;
tst->os_state.exitcode = ARG1;
- /* exit doesn't return anything (it doesn't return.)
- Nevertheless, if we don't do this, the result-not-assigned-
- yet-you-said-you-were-Special assertion in the main syscall
- handling logic will fire. Hence ..
- */
- SET_RESULT(0);
+ SET_STATUS_Success(0);
}
-PRE(sys_sched_yield, MayBlock)
-{
- PRINT("sched_yield()");
- PRE_REG_READ0(long, "sys_sched_yield");
-}
+//zz PRE(sys_sched_yield, SfMayBlock)
+//zz {
+//zz PRINT("sched_yield()");
+//zz PRE_REG_READ0(long, "sys_sched_yield");
+//zz }
-PRE(sys_ni_syscall, Special)
+PRE(sys_ni_syscall)
{
PRINT("non-existent syscall! (ni_syscall)");
PRE_REG_READ0(long, "ni_syscall");
- SET_RESULT( -VKI_ENOSYS );
-}
-
-PRE(sys_set_tid_address, 0)
-{
- PRINT("sys_set_tid_address ( %p )", ARG1);
- PRE_REG_READ1(long, "set_tid_address", int *, tidptr);
-}
-
-PRE(sys_iopl, 0)
-{
- PRINT("sys_iopl ( %d )", ARG1);
- PRE_REG_READ1(long, "iopl", unsigned long, level);
-}
-
-PRE(sys_setxattr, MayBlock)
-{
- PRINT("sys_setxattr ( %p, %p, %p, %llu, %d )",
- ARG1, ARG2, ARG3, (ULong)ARG4, ARG5);
- PRE_REG_READ5(long, "setxattr",
- char *, path, char *, name,
- void *, value, vki_size_t, size, int, flags);
- PRE_MEM_RASCIIZ( "setxattr(path)", ARG1 );
- PRE_MEM_RASCIIZ( "setxattr(name)", ARG2 );
- PRE_MEM_READ( "setxattr(value)", ARG3, ARG4 );
-}
-
-PRE(sys_lsetxattr, MayBlock)
-{
- PRINT("sys_lsetxattr ( %p, %p, %p, %llu, %d )",
- ARG1, ARG2, ARG3, (ULong)ARG4, ARG5);
- PRE_REG_READ5(long, "lsetxattr",
- char *, path, char *, name,
- void *, value, vki_size_t, size, int, flags);
- PRE_MEM_RASCIIZ( "lsetxattr(path)", ARG1 );
- PRE_MEM_RASCIIZ( "lsetxattr(name)", ARG2 );
- PRE_MEM_READ( "lsetxattr(value)", ARG3, ARG4 );
-}
-
-PRE(sys_fsetxattr, MayBlock)
-{
- PRINT("sys_fsetxattr ( %d, %p, %p, %llu, %d )",
- ARG1, ARG2, ARG3, (ULong)ARG4, ARG5);
- PRE_REG_READ5(long, "fsetxattr",
- int, fd, char *, name, void *, value,
- vki_size_t, size, int, flags);
- PRE_MEM_RASCIIZ( "fsetxattr(name)", ARG2 );
- PRE_MEM_READ( "fsetxattr(value)", ARG3, ARG4 );
-}
-
-PRE(sys_getxattr, MayBlock)
-{
+ SET_STATUS_Failure( VKI_ENOSYS );
+}
+
+//zz PRE(sys_set_tid_address, 0)
+//zz {
+//zz PRINT("sys_set_tid_address ( %p )", ARG1);
+//zz PRE_REG_READ1(long, "set_tid_address", int *, tidptr);
+//zz }
+//zz
+//zz PRE(sys_iopl, 0)
+//zz {
+//zz PRINT("sys_iopl ( %d )", ARG1);
+//zz PRE_REG_READ1(long, "iopl", unsigned long, level);
+//zz }
+//zz
+//zz PRE(sys_setxattr, SfMayBlock)
+//zz {
+//zz PRINT("sys_setxattr ( %p, %p, %p, %llu, %d )",
+//zz ARG1, ARG2, ARG3, (ULong)ARG4, ARG5);
+//zz PRE_REG_READ5(long, "setxattr",
+//zz char *, path, char *, name,
+//zz void *, value, vki_size_t, size, int, flags);
+//zz PRE_MEM_RASCIIZ( "setxattr(path)", ARG1 );
+//zz PRE_MEM_RASCIIZ( "setxattr(name)", ARG2 );
+//zz PRE_MEM_READ( "setxattr(value)", ARG3, ARG4 );
+//zz }
+//zz
+//zz PRE(sys_lsetxattr, SfMayBlock)
+//zz {
+//zz PRINT("sys_lsetxattr ( %p, %p, %p, %llu, %d )",
+//zz ARG1, ARG2, ARG3, (ULong)ARG4, ARG5);
+//zz PRE_REG_READ5(long, "lsetxattr",
+//zz char *, path, char *, name,
+//zz void *, value, vki_size_t, size, int, flags);
+//zz PRE_MEM_RASCIIZ( "lsetxattr(path)", ARG1 );
+//zz PRE_MEM_RASCIIZ( "lsetxattr(name)", ARG2 );
+//zz PRE_MEM_READ( "lsetxattr(value)", ARG3, ARG4 );
+//zz }
+//zz
+//zz PRE(sys_fsetxattr, SfMayBlock)
+//zz {
+//zz PRINT("sys_fsetxattr ( %d, %p, %p, %llu, %d )",
+//zz ARG1, ARG2, ARG3, (ULong)ARG4, ARG5);
+//zz PRE_REG_READ5(long, "fsetxattr",
+//zz int, fd, char *, name, void *, value,
+//zz vki_size_t, size, int, flags);
+//zz PRE_MEM_RASCIIZ( "fsetxattr(name)", ARG2 );
+//zz PRE_MEM_READ( "fsetxattr(value)", ARG3, ARG4 );
+//zz }
+
+PRE(sys_getxattr)
+{
+ *flags |= SfMayBlock;
PRINT("sys_getxattr ( %p, %p, %p, %llu )", ARG1,ARG2,ARG3, (ULong)ARG4);
PRE_REG_READ4(ssize_t, "getxattr",
char *, path, char *, name, void *, value, vki_size_t, size);
@@ -1834,266 +1743,268 @@ PRE(sys_getxattr, MayBlock)
POST(sys_getxattr)
{
+ vg_assert(SUCCESS);
if (RES > 0 && ARG3 != (Addr)NULL) {
POST_MEM_WRITE( ARG3, RES );
}
}
-PRE(sys_lgetxattr, MayBlock)
-{
- PRINT("sys_lgetxattr ( %p, %p, %p, %llu )", ARG1,ARG2,ARG3, (ULong)ARG4);
- PRE_REG_READ4(ssize_t, "lgetxattr",
- char *, path, char *, name, void *, value, vki_size_t, size);
- PRE_MEM_RASCIIZ( "lgetxattr(path)", ARG1 );
- PRE_MEM_RASCIIZ( "lgetxattr(name)", ARG2 );
- PRE_MEM_WRITE( "lgetxattr(value)", ARG3, ARG4 );
-}
-
-POST(sys_lgetxattr)
-{
- if (RES > 0 && ARG3 != (Addr)NULL) {
- POST_MEM_WRITE( ARG3, RES );
- }
-}
-
-PRE(sys_fgetxattr, MayBlock)
-{
- PRINT("sys_fgetxattr ( %d, %p, %p, %llu )", ARG1, ARG2, ARG3, (ULong)ARG4);
- PRE_REG_READ4(ssize_t, "fgetxattr",
- int, fd, char *, name, void *, value, vki_size_t, size);
- PRE_MEM_RASCIIZ( "fgetxattr(name)", ARG2 );
- PRE_MEM_WRITE( "fgetxattr(value)", ARG3, ARG4 );
-}
-
-POST(sys_fgetxattr)
-{
- if (RES > 0 && ARG3 != (Addr)NULL)
- POST_MEM_WRITE( ARG3, RES );
-}
-
-PRE(sys_listxattr, MayBlock)
-{
- PRINT("sys_listxattr ( %p, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
- PRE_REG_READ3(ssize_t, "listxattr",
- char *, path, char *, list, vki_size_t, size);
- PRE_MEM_RASCIIZ( "listxattr(path)", ARG1 );
- PRE_MEM_WRITE( "listxattr(list)", ARG2, ARG3 );
-}
-
-POST(sys_listxattr)
-{
- if (RES > 0 && ARG2 != (Addr)NULL)
- POST_MEM_WRITE( ARG2, RES );
-}
-
-PRE(sys_llistxattr, MayBlock)
-{
- PRINT("sys_llistxattr ( %p, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
- PRE_REG_READ3(ssize_t, "llistxattr",
- char *, path, char *, list, vki_size_t, size);
- PRE_MEM_RASCIIZ( "llistxattr(path)", ARG1 );
- PRE_MEM_WRITE( "llistxattr(list)", ARG2, ARG3 );
-}
-
-POST(sys_llistxattr)
-{
- if (RES > 0 && ARG2 != (Addr)NULL)
- POST_MEM_WRITE( ARG2, RES );
-}
-
-PRE(sys_flistxattr, MayBlock)
-{
- PRINT("sys_flistxattr ( %d, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
- PRE_REG_READ3(ssize_t, "flistxattr",
- int, fd, char *, list, vki_size_t, size);
- PRE_MEM_WRITE( "flistxattr(list)", ARG2, ARG3 );
-}
-
-POST(sys_flistxattr)
-{
- if (RES > 0 && ARG2 != (Addr)NULL)
- POST_MEM_WRITE( ARG2, RES );
-}
-
-PRE(sys_removexattr, MayBlock)
-{
- PRINT("sys_removexattr ( %p, %p )", ARG1, ARG2);
- PRE_REG_READ2(long, "removexattr", char *, path, char *, name);
- PRE_MEM_RASCIIZ( "removexattr(path)", ARG1 );
- PRE_MEM_RASCIIZ( "removexattr(name)", ARG2 );
-}
-
-PRE(sys_lremovexattr, MayBlock)
-{
- PRINT("sys_lremovexattr ( %p, %p )", ARG1, ARG2);
- PRE_REG_READ2(long, "lremovexattr", char *, path, char *, name);
- PRE_MEM_RASCIIZ( "lremovexattr(path)", ARG1 );
- PRE_MEM_RASCIIZ( "lremovexattr(name)", ARG2 );
-}
-
-PRE(sys_fremovexattr, MayBlock)
-{
- PRINT("sys_fremovexattr ( %d, %p )", ARG1, ARG2);
- PRE_REG_READ2(long, "fremovexattr", int, fd, char *, name);
- PRE_MEM_RASCIIZ( "fremovexattr(name)", ARG2 );
-}
-
-PRE(sys_quotactl, 0)
-{
- PRINT("sys_quotactl (0x%x, %p, 0x%x, 0x%x )", ARG1,ARG2,ARG3, ARG4);
- PRE_REG_READ4(long, "quotactl",
- unsigned int, cmd, const char *, special, vki_qid_t, id,
- void *, addr);
- PRE_MEM_RASCIIZ( "quotactl(special)", ARG2 );
-}
-
-// XXX: this wrapper is only suitable for 32-bit platforms
-PRE(sys_lookup_dcookie, 0)
-{
- PRINT("sys_lookup_dcookie (0x%llx, %p, %d)", LOHI64(ARG1,ARG2), ARG3, ARG4);
- PRE_REG_READ4(long, "lookup_dcookie",
- vki_u32, cookie_low32, vki_u32, cookie_high32,
- char *, buf, vki_size_t, len);
- PRE_MEM_WRITE( "lookup_dcookie(buf)", ARG3, ARG4);
-}
-
-POST(sys_lookup_dcookie)
-{
- if (ARG3 != (Addr)NULL)
- POST_MEM_WRITE( ARG3, RES);
-}
-
-PRE(sys_fsync, MayBlock)
-{
- PRINT("sys_fsync ( %d )", ARG1);
- PRE_REG_READ1(long, "fsync", unsigned int, fd);
-}
-
-PRE(sys_fdatasync, MayBlock)
-{
- PRINT("sys_fdatasync ( %d )", ARG1);
- PRE_REG_READ1(long, "fdatasync", unsigned int, fd);
-}
-
-PRE(sys_msync, MayBlock)
-{
- PRINT("sys_msync ( %p, %llu, %d )", ARG1,(ULong)ARG2,ARG3);
- PRE_REG_READ3(long, "msync",
- unsigned long, start, vki_size_t, length, int, flags);
- PRE_MEM_READ( "msync(start)", ARG1, ARG2 );
-}
-
-// Nb: getpmsg() and putpmsg() are special additional syscalls used in early
-// versions of LiS (Linux Streams). They are not part of the kernel.
-// Therefore, we have to provide this type ourself, rather than getting it
-// from the kernel sources.
-struct vki_pmsg_strbuf {
- int maxlen; /* no. of bytes in buffer */
- int len; /* no. of bytes returned */
- vki_caddr_t buf; /* pointer to data */
-};
-
-PRE(sys_getpmsg, MayBlock)
-{
- /* LiS getpmsg from http://www.gcom.com/home/linux/lis/ */
- struct vki_pmsg_strbuf *ctrl;
- struct vki_pmsg_strbuf *data;
- PRINT("sys_getpmsg ( %d, %p, %p, %p, %p )", ARG1,ARG2,ARG3,ARG4,ARG5);
- PRE_REG_READ5(int, "getpmsg",
- int, fd, struct strbuf *, ctrl, struct strbuf *, data,
- int *, bandp, int *, flagsp);
- ctrl = (struct vki_pmsg_strbuf *)ARG2;
- data = (struct vki_pmsg_strbuf *)ARG3;
- if (ctrl && ctrl->maxlen > 0)
- PRE_MEM_WRITE( "getpmsg(ctrl)", (Addr)ctrl->buf, ctrl->maxlen);
- if (data && data->maxlen > 0)
- PRE_MEM_WRITE( "getpmsg(data)", (Addr)data->buf, data->maxlen);
- if (ARG4)
- PRE_MEM_WRITE( "getpmsg(bandp)", (Addr)ARG4, sizeof(int));
- if (ARG5)
- PRE_MEM_WRITE( "getpmsg(flagsp)", (Addr)ARG5, sizeof(int));
-}
-
-POST(sys_getpmsg)
-{
- struct vki_pmsg_strbuf *ctrl;
- struct vki_pmsg_strbuf *data;
-
- ctrl = (struct vki_pmsg_strbuf *)ARG2;
- data = (struct vki_pmsg_strbuf *)ARG3;
- if (RES == 0 && ctrl && ctrl->len > 0) {
- POST_MEM_WRITE( (Addr)ctrl->buf, ctrl->len);
- }
- if (RES == 0 && data && data->len > 0) {
- POST_MEM_WRITE( (Addr)data->buf, data->len);
- }
-}
-
-PRE(sys_putpmsg, MayBlock)
-{
- /* LiS putpmsg from http://www.gcom.com/home/linux/lis/ */
- struct vki_pmsg_strbuf *ctrl;
- struct vki_pmsg_strbuf *data;
- PRINT("sys_putpmsg ( %d, %p, %p, %d, %d )", ARG1,ARG2,ARG3,ARG4,ARG5);
- PRE_REG_READ5(int, "putpmsg",
- int, fd, struct strbuf *, ctrl, struct strbuf *, data,
- int, band, int, flags);
- ctrl = (struct vki_pmsg_strbuf *)ARG2;
- data = (struct vki_pmsg_strbuf *)ARG3;
- if (ctrl && ctrl->len > 0)
- PRE_MEM_READ( "putpmsg(ctrl)", (Addr)ctrl->buf, ctrl->len);
- if (data && data->len > 0)
- PRE_MEM_READ( "putpmsg(data)", (Addr)data->buf, data->len);
-}
-
-PRE(sys_getitimer, 0)
-{
- PRINT("sys_getitimer ( %d, %p )", ARG1, ARG2);
- PRE_REG_READ2(long, "getitimer", int, which, struct itimerval *, value);
- PRE_MEM_WRITE( "getitimer(value)", ARG2, sizeof(struct vki_itimerval) );
-}
-
-POST(sys_getitimer)
-{
- if (ARG2 != (Addr)NULL) {
- POST_MEM_WRITE(ARG2, sizeof(struct vki_itimerval));
- }
-}
-
-PRE(sys_setitimer, 0)
-{
- PRINT("sys_setitimer ( %d, %p, %p )", ARG1,ARG2,ARG3);
- PRE_REG_READ3(long, "setitimer",
- int, which,
- struct itimerval *, value, struct itimerval *, ovalue);
- if (ARG2 != (Addr)NULL)
- PRE_MEM_READ( "setitimer(value)", ARG2, sizeof(struct vki_itimerval) );
- if (ARG3 != (Addr)NULL)
- PRE_MEM_WRITE( "setitimer(ovalue)", ARG3, sizeof(struct vki_itimerval));
-}
-
-POST(sys_setitimer)
-{
- if (ARG3 != (Addr)NULL) {
- POST_MEM_WRITE(ARG3, sizeof(struct vki_itimerval));
- }
-}
-
-PRE(sys_chroot, 0)
-{
- PRINT("sys_chroot ( %p )", ARG1);
- PRE_REG_READ1(long, "chroot", const char *, path);
- PRE_MEM_RASCIIZ( "chroot(path)", ARG1 );
-}
-
-PRE(sys_madvise, MayBlock)
-{
+//zz PRE(sys_lgetxattr, SfMayBlock)
+//zz {
+//zz PRINT("sys_lgetxattr ( %p, %p, %p, %llu )", ARG1,ARG2,ARG3, (ULong)ARG4);
+//zz PRE_REG_READ4(ssize_t, "lgetxattr",
+//zz char *, path, char *, name, void *, value, vki_size_t, size);
+//zz PRE_MEM_RASCIIZ( "lgetxattr(path)", ARG1 );
+//zz PRE_MEM_RASCIIZ( "lgetxattr(name)", ARG2 );
+//zz PRE_MEM_WRITE( "lgetxattr(value)", ARG3, ARG4 );
+//zz }
+//zz
+//zz POST(sys_lgetxattr)
+//zz {
+//zz if (RES > 0 && ARG3 != (Addr)NULL) {
+//zz POST_MEM_WRITE( ARG3, RES );
+//zz }
+//zz }
+//zz
+//zz PRE(sys_fgetxattr, SfMayBlock)
+//zz {
+//zz PRINT("sys_fgetxattr ( %d, %p, %p, %llu )", ARG1, ARG2, ARG3, (ULong)ARG4);
+//zz PRE_REG_READ4(ssize_t, "fgetxattr",
+//zz int, fd, char *, name, void *, value, vki_size_t, size);
+//zz PRE_MEM_RASCIIZ( "fgetxattr(name)", ARG2 );
+//zz PRE_MEM_WRITE( "fgetxattr(value)", ARG3, ARG4 );
+//zz }
+//zz
+//zz POST(sys_fgetxattr)
+//zz {
+//zz if (RES > 0 && ARG3 != (Addr)NULL)
+//zz POST_MEM_WRITE( ARG3, RES );
+//zz }
+//zz
+//zz PRE(sys_listxattr, SfMayBlock)
+//zz {
+//zz PRINT("sys_listxattr ( %p, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
+//zz PRE_REG_READ3(ssize_t, "listxattr",
+//zz char *, path, char *, list, vki_size_t, size);
+//zz PRE_MEM_RASCIIZ( "listxattr(path)", ARG1 );
+//zz PRE_MEM_WRITE( "listxattr(list)", ARG2, ARG3 );
+//zz }
+//zz
+//zz POST(sys_listxattr)
+//zz {
+//zz if (RES > 0 && ARG2 != (Addr)NULL)
+//zz POST_MEM_WRITE( ARG2, RES );
+//zz }
+//zz
+//zz PRE(sys_llistxattr, SfMayBlock)
+//zz {
+//zz PRINT("sys_llistxattr ( %p, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
+//zz PRE_REG_READ3(ssize_t, "llistxattr",
+//zz char *, path, char *, list, vki_size_t, size);
+//zz PRE_MEM_RASCIIZ( "llistxattr(path)", ARG1 );
+//zz PRE_MEM_WRITE( "llistxattr(list)", ARG2, ARG3 );
+//zz }
+//zz
+//zz POST(sys_llistxattr)
+//zz {
+//zz if (RES > 0 && ARG2 != (Addr)NULL)
+//zz POST_MEM_WRITE( ARG2, RES );
+//zz }
+//zz
+//zz PRE(sys_flistxattr, SfMayBlock)
+//zz {
+//zz PRINT("sys_flistxattr ( %d, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
+//zz PRE_REG_READ3(ssize_t, "flistxattr",
+//zz int, fd, char *, list, vki_size_t, size);
+//zz PRE_MEM_WRITE( "flistxattr(list)", ARG2, ARG3 );
+//zz }
+//zz
+//zz POST(sys_flistxattr)
+//zz {
+//zz if (RES > 0 && ARG2 != (Addr)NULL)
+//zz POST_MEM_WRITE( ARG2, RES );
+//zz }
+//zz
+//zz PRE(sys_removexattr, SfMayBlock)
+//zz {
+//zz PRINT("sys_removexattr ( %p, %p )", ARG1, ARG2);
+//zz PRE_REG_READ2(long, "removexattr", char *, path, char *, name);
+//zz PRE_MEM_RASCIIZ( "removexattr(path)", ARG1 );
+//zz PRE_MEM_RASCIIZ( "removexattr(name)", ARG2 );
+//zz }
+//zz
+//zz PRE(sys_lremovexattr, SfMayBlock)
+//zz {
+//zz PRINT("sys_lremovexattr ( %p, %p )", ARG1, ARG2);
+//zz PRE_REG_READ2(long, "lremovexattr", char *, path, char *, name);
+//zz PRE_MEM_RASCIIZ( "lremovexattr(path)", ARG1 );
+//zz PRE_MEM_RASCIIZ( "lremovexattr(name)", ARG2 );
+//zz }
+//zz
+//zz PRE(sys_fremovexattr, SfMayBlock)
+//zz {
+//zz PRINT("sys_fremovexattr ( %d, %p )", ARG1, ARG2);
+//zz PRE_REG_READ2(long, "fremovexattr", int, fd, char *, name);
+//zz PRE_MEM_RASCIIZ( "fremovexattr(name)", ARG2 );
+//zz }
+//zz
+//zz PRE(sys_quotactl, 0)
+//zz {
+//zz PRINT("sys_quotactl (0x%x, %p, 0x%x, 0x%x )", ARG1,ARG2,ARG3, ARG4);
+//zz PRE_REG_READ4(long, "quotactl",
+//zz unsigned int, cmd, const char *, special, vki_qid_t, id,
+//zz void *, addr);
+//zz PRE_MEM_RASCIIZ( "quotactl(special)", ARG2 );
+//zz }
+//zz
+//zz // XXX: this wrapper is only suitable for 32-bit platforms
+//zz PRE(sys_lookup_dcookie, 0)
+//zz {
+//zz PRINT("sys_lookup_dcookie (0x%llx, %p, %d)", LOHI64(ARG1,ARG2), ARG3, ARG4);
+//zz PRE_REG_READ4(long, "lookup_dcookie",
+//zz vki_u32, cookie_low32, vki_u32, cookie_high32,
+//zz char *, buf, vki_size_t, len);
+//zz PRE_MEM_WRITE( "lookup_dcookie(buf)", ARG3, ARG4);
+//zz }
+//zz
+//zz POST(sys_lookup_dcookie)
+//zz {
+//zz if (ARG3 != (Addr)NULL)
+//zz POST_MEM_WRITE( ARG3, RES);
+//zz }
+//zz
+//zz PRE(sys_fsync, SfMayBlock)
+//zz {
+//zz PRINT("sys_fsync ( %d )", ARG1);
+//zz PRE_REG_READ1(long, "fsync", unsigned int, fd);
+//zz }
+//zz
+//zz PRE(sys_fdatasync, SfMayBlock)
+//zz {
+//zz PRINT("sys_fdatasync ( %d )", ARG1);
+//zz PRE_REG_READ1(long, "fdatasync", unsigned int, fd);
+//zz }
+//zz
+//zz PRE(sys_msync, SfMayBlock)
+//zz {
+//zz PRINT("sys_msync ( %p, %llu, %d )", ARG1,(ULong)ARG2,ARG3);
+//zz PRE_REG_READ3(long, "msync",
+//zz unsigned long, start, vki_size_t, length, int, flags);
+//zz PRE_MEM_READ( "msync(start)", ARG1, ARG2 );
+//zz }
+//zz
+//zz // Nb: getpmsg() and putpmsg() are special additional syscalls used in early
+//zz // versions of LiS (Linux Streams). They are not part of the kernel.
+//zz // Therefore, we have to provide this type ourself, rather than getting it
+//zz // from the kernel sources.
+//zz struct vki_pmsg_strbuf {
+//zz int maxlen; /* no. of bytes in buffer */
+//zz int len; /* no. of bytes returned */
+//zz vki_caddr_t buf; /* pointer to data */
+//zz };
+//zz
+//zz PRE(sys_getpmsg, SfMayBlock)
+//zz {
+//zz /* LiS getpmsg from http://www.gcom.com/home/linux/lis/ */
+//zz struct vki_pmsg_strbuf *ctrl;
+//zz struct vki_pmsg_strbuf *data;
+//zz PRINT("sys_getpmsg ( %d, %p, %p, %p, %p )", ARG1,ARG2,ARG3,ARG4,ARG5);
+//zz PRE_REG_READ5(int, "getpmsg",
+//zz int, fd, struct strbuf *, ctrl, struct strbuf *, data,
+//zz int *, bandp, int *, flagsp);
+//zz ctrl = (struct vki_pmsg_strbuf *)ARG2;
+//zz data = (struct vki_pmsg_strbuf *)ARG3;
+//zz if (ctrl && ctrl->maxlen > 0)
+//zz PRE_MEM_WRITE( "getpmsg(ctrl)", (Addr)ctrl->buf, ctrl->maxlen);
+//zz if (data && data->maxlen > 0)
+//zz PRE_MEM_WRITE( "getpmsg(data)", (Addr)data->buf, data->maxlen);
+//zz if (ARG4)
+//zz PRE_MEM_WRITE( "getpmsg(bandp)", (Addr)ARG4, sizeof(int));
+//zz if (ARG5)
+//zz PRE_MEM_WRITE( "getpmsg(flagsp)", (Addr)ARG5, sizeof(int));
+//zz }
+//zz
+//zz POST(sys_getpmsg)
+//zz {
+//zz struct vki_pmsg_strbuf *ctrl;
+//zz struct vki_pmsg_strbuf *data;
+//zz
+//zz ctrl = (struct vki_pmsg_strbuf *)ARG2;
+//zz data = (struct vki_pmsg_strbuf *)ARG3;
+//zz if (RES == 0 && ctrl && ctrl->len > 0) {
+//zz POST_MEM_WRITE( (Addr)ctrl->buf, ctrl->len);
+//zz }
+//zz if (RES == 0 && data && data->len > 0) {
+//zz POST_MEM_WRITE( (Addr)data->buf, data->len);
+//zz }
+//zz }
+//zz
+//zz PRE(sys_putpmsg, SfMayBlock)
+//zz {
+//zz /* LiS putpmsg from http://www.gcom.com/home/linux/lis/ */
+//zz struct vki_pmsg_strbuf *ctrl;
+//zz struct vki_pmsg_strbuf *data;
+//zz PRINT("sys_putpmsg ( %d, %p, %p, %d, %d )", ARG1,ARG2,ARG3,ARG4,ARG5);
+//zz PRE_REG_READ5(int, "putpmsg",
+//zz int, fd, struct strbuf *, ctrl, struct strbuf *, data,
+//zz int, band, int, flags);
+//zz ctrl = (struct vki_pmsg_strbuf *)ARG2;
+//zz data = (struct vki_pmsg_strbuf *)ARG3;
+//zz if (ctrl && ctrl->len > 0)
+//zz PRE_MEM_READ( "putpmsg(ctrl)", (Addr)ctrl->buf, ctrl->len);
+//zz if (data && data->len > 0)
+//zz PRE_MEM_READ( "putpmsg(data)", (Addr)data->buf, data->len);
+//zz }
+//zz
+//zz PRE(sys_getitimer, 0)
+//zz {
+//zz PRINT("sys_getitimer ( %d, %p )", ARG1, ARG2);
+//zz PRE_REG_READ2(long, "getitimer", int, which, struct itimerval *, value);
+//zz PRE_MEM_WRITE( "getitimer(value)", ARG2, sizeof(struct vki_itimerval) );
+//zz }
+//zz
+//zz POST(sys_getitimer)
+//zz {
+//zz if (ARG2 != (Addr)NULL) {
+//zz POST_MEM_WRITE(ARG2, sizeof(struct vki_itimerval));
+//zz }
+//zz }
+//zz
+//zz PRE(sys_setitimer, 0)
+//zz {
+//zz PRINT("sys_setitimer ( %d, %p, %p )", ARG1,ARG2,ARG3);
+//zz PRE_REG_READ3(long, "setitimer",
+//zz int, which,
+//zz struct itimerval *, value, struct itimerval *, ovalue);
+//zz if (ARG2 != (Addr)NULL)
+//zz PRE_MEM_READ( "setitimer(value)", ARG2, sizeof(struct vki_itimerval) );
+//zz if (ARG3 != (Addr)NULL)
+//zz PRE_MEM_WRITE( "setitimer(ovalue)", ARG3, sizeof(struct vki_itimerval));
+//zz }
+//zz
+//zz POST(sys_setitimer)
+//zz {
+//zz if (ARG3 != (Addr)NULL) {
+//zz POST_MEM_WRITE(ARG3, sizeof(struct vki_itimerval));
+//zz }
+//zz }
+//zz
+//zz PRE(sys_chroot, 0)
+//zz {
+//zz PRINT("sys_chroot ( %p )", ARG1);
+//zz PRE_REG_READ1(long, "chroot", const char *, path);
+//zz PRE_MEM_RASCIIZ( "chroot(path)", ARG1 );
+//zz }
+
+PRE(sys_madvise)
+{
+ *flags |= SfMayBlock;
PRINT("sys_madvise ( %p, %llu, %d )", ARG1,(ULong)ARG2,ARG3);
PRE_REG_READ3(long, "madvise",
unsigned long, start, vki_size_t, length, int, advice);
}
-PRE(sys_mremap, Special)
+PRE(sys_mremap)
{
// Nb: this is different to the glibc version described in the man pages,
// which lacks the fifth 'new_address' argument.
@@ -2103,153 +2014,155 @@ PRE(sys_mremap, Special)
unsigned long, old_addr, unsigned long, old_size,
unsigned long, new_size, unsigned long, flags,
unsigned long, new_addr);
- SET_RESULT( mremap_segment((Addr)ARG1, ARG2, (Addr)ARG5, ARG3, ARG4, tid) );
-}
-
-PRE(sys_nice, 0)
-{
- PRINT("sys_nice ( %d )", ARG1);
- PRE_REG_READ1(long, "nice", int, inc);
-}
-
-PRE(sys_sched_getscheduler, 0)
-{
- PRINT("sys_sched_getscheduler ( %d )", ARG1);
- PRE_REG_READ1(long, "sched_getscheduler", vki_pid_t, pid);
-}
-
-PRE(sys_sched_setscheduler, 0)
-{
- PRINT("sys_sched_setscheduler ( %d, %d, %p )", ARG1,ARG2,ARG3);
- PRE_REG_READ3(long, "sched_setscheduler",
- vki_pid_t, pid, int, policy, struct sched_param *, p);
- if (ARG3 != 0)
- PRE_MEM_READ( "sched_setscheduler(p)",
- ARG3, sizeof(struct vki_sched_param));
-}
-
-PRE(sys_mlock, MayBlock)
-{
- PRINT("sys_mlock ( %p, %llu )", ARG1, (ULong)ARG2);
- PRE_REG_READ2(long, "mlock", unsigned long, addr, vki_size_t, len);
-}
-
-PRE(sys_munlock, MayBlock)
-{
- PRINT("sys_munlock ( %p, %llu )", ARG1, (ULong)ARG2);
- PRE_REG_READ2(long, "munlock", unsigned long, addr, vki_size_t, len);
-}
-
-PRE(sys_mlockall, MayBlock)
-{
- PRINT("sys_mlockall ( %x )", ARG1);
- PRE_REG_READ1(long, "mlockall", int, flags);
-}
-
-PRE(sys_munlockall, MayBlock)
-{
- PRINT("sys_munlockall ( )");
- PRE_REG_READ0(long, "munlockall");
-}
-
-PRE(sys_sched_get_priority_max, 0)
-{
- PRINT("sched_get_priority_max ( %d )", ARG1);
- PRE_REG_READ1(long, "sched_get_priority_max", int, policy);
-}
-
-PRE(sys_sched_get_priority_min, 0)
-{
- PRINT("sched_get_priority_min ( %d )", ARG1);
- PRE_REG_READ1(long, "sched_get_priority_min", int, policy);
-}
-
-PRE(sys_setpriority, 0)
-{
- PRINT("sys_setpriority ( %d, %d, %d )", ARG1, ARG2, ARG3);
- PRE_REG_READ3(long, "setpriority", int, which, int, who, int, prio);
-}
-
-PRE(sys_getpriority, 0)
-{
- PRINT("sys_getpriority ( %d, %d )", ARG1, ARG2);
- PRE_REG_READ2(long, "getpriority", int, which, int, who);
-}
-
-PRE(sys_setregid16, 0)
-{
- PRINT("sys_setregid16 ( %d, %d )", ARG1, ARG2);
- PRE_REG_READ2(long, "setregid16", vki_old_gid_t, rgid, vki_old_gid_t, egid);
-}
-
-// XXX: only for 32-bit archs
-PRE(sys_pwrite64, MayBlock)
-{
- PRINT("sys_pwrite64 ( %d, %p, %llu, %lld )",
- ARG1, ARG2, (ULong)ARG3, LOHI64(ARG4,ARG5));
- PRE_REG_READ5(ssize_t, "pwrite64",
- unsigned int, fd, const char *, buf, vki_size_t, count,
- vki_u32, offset_low32, vki_u32, offset_high32);
- PRE_MEM_READ( "pwrite64(buf)", ARG2, ARG3 );
-}
-
-PRE(sys_sync, MayBlock)
-{
- PRINT("sys_sync ( )");
- PRE_REG_READ0(long, "sync");
-}
-
-PRE(sys_fstatfs, 0)
-{
- PRINT("sys_fstatfs ( %d, %p )",ARG1,ARG2);
- PRE_REG_READ2(long, "fstatfs",
- unsigned int, fd, struct statfs *, buf);
- PRE_MEM_WRITE( "fstatfs(buf)", ARG2, sizeof(struct vki_statfs) );
-}
-
-POST(sys_fstatfs)
-{
- POST_MEM_WRITE( ARG2, sizeof(struct vki_statfs) );
-}
-
-PRE(sys_fstatfs64, 0)
-{
- PRINT("sys_fstatfs64 ( %d, %llu, %p )",ARG1,(ULong)ARG2,ARG3);
- PRE_REG_READ3(long, "fstatfs64",
- unsigned int, fd, vki_size_t, size, struct statfs64 *, buf);
- PRE_MEM_WRITE( "fstatfs64(buf)", ARG3, ARG2 );
-}
-
-POST(sys_fstatfs64)
-{
- POST_MEM_WRITE( ARG3, ARG2 );
-}
-
-PRE(sys_getsid, 0)
-{
- PRINT("sys_getsid ( %d )", ARG1);
- PRE_REG_READ1(long, "getsid", vki_pid_t, pid);
-}
-
-// XXX: only for 32-bit archs
-PRE(sys_pread64, MayBlock)
-{
- PRINT("sys_pread64 ( %d, %p, %llu, %lld )",
- ARG1, ARG2, (ULong)ARG3, LOHI64(ARG4,ARG5));
- PRE_REG_READ5(ssize_t, "pread64",
- unsigned int, fd, char *, buf, vki_size_t, count,
- vki_u32, offset_low32, vki_u32, offset_high32);
- PRE_MEM_WRITE( "pread64(buf)", ARG2, ARG3 );
-}
-
-POST(sys_pread64)
-{
- if (RES > 0) {
- POST_MEM_WRITE( ARG2, RES );
- }
+ SET_STATUS_from_SysRes(
+ mremap_segment((Addr)ARG1, ARG2, (Addr)ARG5, ARG3, ARG4, tid)
+ );
}
-PRE(sys_mknod, 0)
+//zz PRE(sys_nice, 0)
+//zz {
+//zz PRINT("sys_nice ( %d )", ARG1);
+//zz PRE_REG_READ1(long, "nice", int, inc);
+//zz }
+//zz
+//zz PRE(sys_sched_getscheduler, 0)
+//zz {
+//zz PRINT("sys_sched_getscheduler ( %d )", ARG1);
+//zz PRE_REG_READ1(long, "sched_getscheduler", vki_pid_t, pid);
+//zz }
+//zz
+//zz PRE(sys_sched_setscheduler, 0)
+//zz {
+//zz PRINT("sys_sched_setscheduler ( %d, %d, %p )", ARG1,ARG2,ARG3);
+//zz PRE_REG_READ3(long, "sched_setscheduler",
+//zz vki_pid_t, pid, int, policy, struct sched_param *, p);
+//zz if (ARG3 != 0)
+//zz PRE_MEM_READ( "sched_setscheduler(p)",
+//zz ARG3, sizeof(struct vki_sched_param));
+//zz }
+//zz
+//zz PRE(sys_mlock, SfMayBlock)
+//zz {
+//zz PRINT("sys_mlock ( %p, %llu )", ARG1, (ULong)ARG2);
+//zz PRE_REG_READ2(long, "mlock", unsigned long, addr, vki_size_t, len);
+//zz }
+//zz
+//zz PRE(sys_munlock, SfMayBlock)
+//zz {
+//zz PRINT("sys_munlock ( %p, %llu )", ARG1, (ULong)ARG2);
+//zz PRE_REG_READ2(long, "munlock", unsigned long, addr, vki_size_t, len);
+//zz }
+//zz
+//zz PRE(sys_mlockall, SfMayBlock)
+//zz {
+//zz PRINT("sys_mlockall ( %x )", ARG1);
+//zz PRE_REG_READ1(long, "mlockall", int, flags);
+//zz }
+//zz
+//zz PRE(sys_munlockall, SfMayBlock)
+//zz {
+//zz PRINT("sys_munlockall ( )");
+//zz PRE_REG_READ0(long, "munlockall");
+//zz }
+//zz
+//zz PRE(sys_sched_get_priority_max, 0)
+//zz {
+//zz PRINT("sched_get_priority_max ( %d )", ARG1);
+//zz PRE_REG_READ1(long, "sched_get_priority_max", int, policy);
+//zz }
+//zz
+//zz PRE(sys_sched_get_priority_min, 0)
+//zz {
+//zz PRINT("sched_get_priority_min ( %d )", ARG1);
+//zz PRE_REG_READ1(long, "sched_get_priority_min", int, policy);
+//zz }
+//zz
+//zz PRE(sys_setpriority, 0)
+//zz {
+//zz PRINT("sys_setpriority ( %d, %d, %d )", ARG1, ARG2, ARG3);
+//zz PRE_REG_READ3(long, "setpriority", int, which, int, who, int, prio);
+//zz }
+//zz
+//zz PRE(sys_getpriority, 0)
+//zz {
+//zz PRINT("sys_getpriority ( %d, %d )", ARG1, ARG2);
+//zz PRE_REG_READ2(long, "getpriority", int, which, int, who);
+//zz }
+//zz
+//zz PRE(sys_setregid16, 0)
+//zz {
+//zz PRINT("sys_setregid16 ( %d, %d )", ARG1, ARG2);
+//zz PRE_REG_READ2(long, "setregid16", vki_old_gid_t, rgid, vki_old_gid_t, egid);
+//zz }
+//zz
+//zz // XXX: only for 32-bit archs
+//zz PRE(sys_pwrite64, SfMayBlock)
+//zz {
+//zz PRINT("sys_pwrite64 ( %d, %p, %llu, %lld )",
+//zz ARG1, ARG2, (ULong)ARG3, LOHI64(ARG4,ARG5));
+//zz PRE_REG_READ5(ssize_t, "pwrite64",
+//zz unsigned int, fd, const char *, buf, vki_size_t, count,
+//zz vki_u32, offset_low32, vki_u32, offset_high32);
+//zz PRE_MEM_READ( "pwrite64(buf)", ARG2, ARG3 );
+//zz }
+//zz
+//zz PRE(sys_sync, SfMayBlock)
+//zz {
+//zz PRINT("sys_sync ( )");
+//zz PRE_REG_READ0(long, "sync");
+//zz }
+//zz
+//zz PRE(sys_fstatfs, 0)
+//zz {
+//zz PRINT("sys_fstatfs ( %d, %p )",ARG1,ARG2);
+//zz PRE_REG_READ2(long, "fstatfs",
+//zz unsigned int, fd, struct statfs *, buf);
+//zz PRE_MEM_WRITE( "fstatfs(buf)", ARG2, sizeof(struct vki_statfs) );
+//zz }
+//zz
+//zz POST(sys_fstatfs)
+//zz {
+//zz POST_MEM_WRITE( ARG2, sizeof(struct vki_statfs) );
+//zz }
+//zz
+//zz PRE(sys_fstatfs64, 0)
+//zz {
+//zz PRINT("sys_fstatfs64 ( %d, %llu, %p )",ARG1,(ULong)ARG2,ARG3);
+//zz PRE_REG_READ3(long, "fstatfs64",
+//zz unsigned int, fd, vki_size_t, size, struct statfs64 *, buf);
+//zz PRE_MEM_WRITE( "fstatfs64(buf)", ARG3, ARG2 );
+//zz }
+//zz
+//zz POST(sys_fstatfs64)
+//zz {
+//zz POST_MEM_WRITE( ARG3, ARG2 );
+//zz }
+//zz
+//zz PRE(sys_getsid, 0)
+//zz {
+//zz PRINT("sys_getsid ( %d )", ARG1);
+//zz PRE_REG_READ1(long, "getsid", vki_pid_t, pid);
+//zz }
+//zz
+//zz // XXX: only for 32-bit archs
+//zz PRE(sys_pread64, SfMayBlock)
+//zz {
+//zz PRINT("sys_pread64 ( %d, %p, %llu, %lld )",
+//zz ARG1, ARG2, (ULong)ARG3, LOHI64(ARG4,ARG5));
+//zz PRE_REG_READ5(ssize_t, "pread64",
+//zz unsigned int, fd, char *, buf, vki_size_t, count,
+//zz vki_u32, offset_low32, vki_u32, offset_high32);
+//zz PRE_MEM_WRITE( "pread64(buf)", ARG2, ARG3 );
+//zz }
+//zz
+//zz POST(sys_pread64)
+//zz {
+//zz if (RES > 0) {
+//zz POST_MEM_WRITE( ARG2, RES );
+//zz }
+//zz }
+
+PRE(sys_mknod)
{
PRINT("sys_mknod ( %p, 0x%x, 0x%x )", ARG1, ARG2, ARG3 );
PRE_REG_READ3(long, "mknod",
@@ -2257,49 +2170,49 @@ PRE(sys_mknod, 0)
PRE_MEM_RASCIIZ( "mknod(pathname)", ARG1 );
}
-PRE(sys_flock, MayBlock)
-{
- PRINT("sys_flock ( %d, %d )", ARG1, ARG2 );
- PRE_REG_READ2(long, "flock", unsigned int, fd, unsigned int, operation);
-}
-
-PRE(sys_init_module, MayBlock)
-{
- PRINT("sys_init_module ( %p, %llu, %p )", ARG1, (ULong)ARG2, ARG3 );
- PRE_REG_READ3(long, "init_module",
- void *, umod, unsigned long, len, const char *, uargs);
- PRE_MEM_READ( "init_module(umod)", ARG1, ARG2 );
- PRE_MEM_RASCIIZ( "init_module(uargs)", ARG3 );
-}
-
-PRE(sys_capget, 0)
-{
- PRINT("sys_capget ( %p, %p )", ARG1, ARG2 );
- PRE_REG_READ2(long, "capget",
- vki_cap_user_header_t, header, vki_cap_user_data_t, data);
- PRE_MEM_READ( "capget(header)", ARG1,
- sizeof(struct __vki_user_cap_header_struct) );
- PRE_MEM_WRITE( "capget(data)", ARG2,
- sizeof(struct __vki_user_cap_data_struct) );
-}
-
-POST(sys_capget)
-{
- if (ARG2 != (Addr)NULL)
- POST_MEM_WRITE( ARG2, sizeof(struct __vki_user_cap_data_struct) );
-}
-
-PRE(sys_capset, 0)
-{
- PRINT("sys_capset ( %p, %p )", ARG1, ARG2 );
- PRE_REG_READ2(long, "capset",
- vki_cap_user_header_t, header,
- const vki_cap_user_data_t, data);
- PRE_MEM_READ( "capset(header)",
- ARG1, sizeof(struct __vki_user_cap_header_struct) );
- PRE_MEM_READ( "capset(data)",
- ARG2, sizeof(struct __vki_user_cap_data_struct) );
-}
+//zz PRE(sys_flock, SfMayBlock)
+//zz {
+//zz PRINT("sys_flock ( %d, %d )", ARG1, ARG2 );
+//zz PRE_REG_READ2(long, "flock", unsigned int, fd, unsigned int, operation);
+//zz }
+//zz
+//zz PRE(sys_init_module, SfMayBlock)
+//zz {
+//zz PRINT("sys_init_module ( %p, %llu, %p )", ARG1, (ULong)ARG2, ARG3 );
+//zz PRE_REG_READ3(long, "init_module",
+//zz void *, umod, unsigned long, len, const char *, uargs);
+//zz PRE_MEM_READ( "init_module(umod)", ARG1, ARG2 );
+//zz PRE_MEM_RASCIIZ( "init_module(uargs)", ARG3 );
+//zz }
+//zz
+//zz PRE(sys_capget, 0)
+//zz {
+//zz PRINT("sys_capget ( %p, %p )", ARG1, ARG2 );
+//zz PRE_REG_READ2(long, "capget",
+//zz vki_cap_user_header_t, header, vki_cap_user_data_t, data);
+//zz PRE_MEM_READ( "capget(header)", ARG1,
+//zz sizeof(struct __vki_user_cap_header_struct) );
+//zz PRE_MEM_WRITE( "capget(data)", ARG2,
+//zz sizeof(struct __vki_user_cap_data_struct) );
+//zz }
+//zz
+//zz POST(sys_capget)
+//zz {
+//zz if (ARG2 != (Addr)NULL)
+//zz POST_MEM_WRITE( ARG2, sizeof(struct __vki_user_cap_data_struct) );
+//zz }
+//zz
+//zz PRE(sys_capset, 0)
+//zz {
+//zz PRINT("sys_capset ( %p, %p )", ARG1, ARG2 );
+//zz PRE_REG_READ2(long, "capset",
+//zz vki_cap_user_header_t, header,
+//zz const vki_cap_user_data_t, data);
+//zz PRE_MEM_READ( "capset(header)",
+//zz ARG1, sizeof(struct __vki_user_cap_header_struct) );
+//zz PRE_MEM_READ( "capset(data)",
+//zz ARG2, sizeof(struct __vki_user_cap_data_struct) );
+//zz }
// Pre_read a char** argument.
static void pre_argv_envp(Addr a, ThreadId tid, Char* s1, Char* s2)
@@ -2318,9 +2231,10 @@ static void pre_argv_envp(Addr a, ThreadId tid, Char* s1, Char* s2)
// XXX: prototype here seemingly doesn't match the prototype for i386-linux,
// but it seems to work nonetheless...
-PRE(sys_execve, Special)
+PRE(sys_execve)
{
- Char *path; /* path to executable */
+ Char* path; /* path to executable */
+ ThreadState* tst;
PRINT("sys_execve ( %p(%s), %p, %p )", ARG1, ARG1, ARG2, ARG3);
PRE_REG_READ3(vki_off_t, "execve",
@@ -2333,6 +2247,9 @@ PRE(sys_execve, Special)
path = (Char *)ARG1;
+ vg_assert(VG_(is_valid_tid)(tid));
+ tst = VG_(get_ThreadState)(tid);
+
/* Erk. If the exec fails, then the following will have made a
mess of things which makes it hard for us to continue. The
right thing to do is piece everything together again in
@@ -2341,17 +2258,18 @@ PRE(sys_execve, Special)
exec. */
{
struct vki_stat st;
- Int ret = VG_(stat)((Char *)ARG1, &st);
+ Int i = VG_(stat)((Char *)ARG1, &st);
- if (ret < 0) {
- SET_RESULT( ret );
+ if (i == -1) {
+ /* stat failed */
+ SET_STATUS_Failure( VKI_EACCES/*really, we should copy stat's result*/ );
return;
}
/* just look for regular file with any X bit set
XXX do proper permissions check?
*/
if ((st.st_mode & 0100111) == 0100000) {
- SET_RESULT( -VKI_EACCES );
+ SET_STATUS_Failure( VKI_EACCES );
return;
}
}
@@ -2439,7 +2357,9 @@ PRE(sys_execve, Special)
VG_(sigprocmask)(VKI_SIG_SETMASK, &tst->sig_mask, NULL);
}
- SET_RESULT( VG_(do_syscall3)(__NR_execve, (UWord)path, ARG2, ARG3) );
+ SET_STATUS_from_SysRes(
+ VG_(do_syscall3)(__NR_execve, (UWord)path, ARG2, ARG3)
+ );
/* If we got here, then the execve failed. We've already made too
much of a mess of ourselves to continue, so we have to abort. */
@@ -2447,27 +2367,28 @@ PRE(sys_execve, Special)
ARG1, ARG1, ARG2, ARG3, -RES);
VG_(message)(Vg_UserMsg, "EXEC FAILED: I can't recover from "
"execve() failing, so I'm dying.");
- VG_(message)(Vg_UserMsg, "Add more stringent tests in PRE(execve), "
+ VG_(message)(Vg_UserMsg, "Add more stringent tests in PRE(sys_execve), "
"or work out how to recover.");
VG_(exit)(101);
}
-PRE(sys_access, 0)
+PRE(sys_access)
{
PRINT("sys_access ( %p(%s), %d )", ARG1,ARG1,ARG2);
PRE_REG_READ2(long, "access", const char *, pathname, int, mode);
PRE_MEM_RASCIIZ( "access(pathname)", ARG1 );
}
-PRE(sys_alarm, 0)
+PRE(sys_alarm)
{
PRINT("sys_alarm ( %d )", ARG1);
PRE_REG_READ1(unsigned long, "alarm", unsigned int, seconds);
}
-PRE(sys_brk, Special)
+PRE(sys_brk)
{
Addr brk_limit = VG_(brk_limit);
+ Addr brk_new;
/* libc says: int brk(void *end_data_segment);
kernel says: void* brk(void* end_data_segment); (more or less)
@@ -2487,74 +2408,75 @@ PRE(sys_brk, Special)
PRINT("sys_brk ( %p )", ARG1);
PRE_REG_READ1(unsigned long, "brk", unsigned long, end_data_segment);
- SET_RESULT( do_brk(ARG1) );
+ brk_new = do_brk(ARG1);
+ SET_STATUS_Success( brk_new );
- if (RES == ARG1) {
+ if (brk_new == ARG1) {
/* brk() succeeded */
- if (RES < brk_limit) {
+ if (brk_new < brk_limit) {
/* successfully shrunk the data segment. */
VG_TRACK( die_mem_brk, (Addr)ARG1,
brk_limit-ARG1 );
} else
- if (RES > brk_limit) {
+ if (brk_new > brk_limit) {
/* successfully grew the data segment */
VG_TRACK( new_mem_brk, brk_limit,
ARG1-brk_limit );
}
} else {
/* brk() failed */
- vg_assert(brk_limit == RES);
+ vg_assert(brk_limit == brk_new);
}
}
-PRE(sys_chdir, 0)
+PRE(sys_chdir)
{
PRINT("sys_chdir ( %p )", ARG1);
PRE_REG_READ1(long, "chdir", const char *, path);
PRE_MEM_RASCIIZ( "chdir(path)", ARG1 );
}
-PRE(sys_chmod, 0)
+PRE(sys_chmod)
{
PRINT("sys_chmod ( %p, %d )", ARG1,ARG2);
PRE_REG_READ2(long, "chmod", const char *, path, vki_mode_t, mode);
PRE_MEM_RASCIIZ( "chmod(path)", ARG1 );
}
-PRE(sys_chown16, 0)
-{
- PRINT("sys_chown16 ( %p, 0x%x, 0x%x )", ARG1,ARG2,ARG3);
- PRE_REG_READ3(long, "chown16",
- const char *, path,
- vki_old_uid_t, owner, vki_old_gid_t, group);
- PRE_MEM_RASCIIZ( "chown16(path)", ARG1 );
-}
-
-PRE(sys_chown, 0)
-{
- /* int chown(const char *path, uid_t owner, gid_t group); */
- PRINT("sys_chown ( %p, 0x%x, 0x%x )", ARG1,ARG2,ARG3);
- PRE_REG_READ3(long, "chown",
- const char *, path, vki_uid_t, owner, vki_gid_t, group);
- PRE_MEM_RASCIIZ( "chown(path)", ARG1 );
-}
-
-PRE(sys_lchown, 0)
-{
- PRINT("sys_lchown ( %p, 0x%x, 0x%x )", ARG1,ARG2,ARG3);
- PRE_REG_READ3(long, "lchown",
- const char *, path, vki_uid_t, owner, vki_gid_t, group);
- PRE_MEM_RASCIIZ( "lchown(path)", ARG1 );
-}
-
-PRE(sys_close, 0)
+//zz PRE(sys_chown16, 0)
+//zz {
+//zz PRINT("sys_chown16 ( %p, 0x%x, 0x%x )", ARG1,ARG2,ARG3);
+//zz PRE_REG_READ3(long, "chown16",
+//zz const char *, path,
+//zz vki_old_uid_t, owner, vki_old_gid_t, group);
+//zz PRE_MEM_RASCIIZ( "chown16(path)", ARG1 );
+//zz }
+//zz
+//zz PRE(sys_chown, 0)
+//zz {
+//zz /* int chown(const char *path, uid_t owner, gid_t group); */
+//zz PRINT("sys_chown ( %p, 0x%x, 0x%x )", ARG1,ARG2,ARG3);
+//zz PRE_REG_READ3(long, "chown",
+//zz const char *, path, vki_uid_t, owner, vki_gid_t, group);
+//zz PRE_MEM_RASCIIZ( "chown(path)", ARG1 );
+//zz }
+//zz
+//zz PRE(sys_lchown, 0)
+//zz {
+//zz PRINT("sys_lchown ( %p, 0x%x, 0x%x )", ARG1,ARG2,ARG3);
+//zz PRE_REG_READ3(long, "lchown",
+//zz const char *, path, vki_uid_t, owner, vki_gid_t, group);
+//zz PRE_MEM_RASCIIZ( "lchown(path)", ARG1 );
+//zz }
+
+PRE(sys_close)
{
PRINT("sys_close ( %d )", ARG1);
PRE_REG_READ1(long, "close", unsigned int, fd);
/* Detect and negate attempts by the client to close Valgrind's log fd */
if (!VG_(fd_allowed)(ARG1, "close", tid, False))
- SET_RESULT( -VKI_EBADF );
+ SET_STATUS_Failure( VKI_EBADF );
}
POST(sys_close)
@@ -2562,7 +2484,7 @@ POST(sys_close)
if (VG_(clo_track_fds)) record_fd_close(tid, ARG1);
}
-PRE(sys_dup, 0)
+PRE(sys_dup)
{
PRINT("sys_dup ( %d )", ARG1);
PRE_REG_READ1(long, "dup", unsigned int, oldfd);
@@ -2570,117 +2492,119 @@ PRE(sys_dup, 0)
POST(sys_dup)
{
+ vg_assert(SUCCESS);
if (!VG_(fd_allowed)(RES, "dup", tid, True)) {
VG_(close)(RES);
- SET_RESULT( -VKI_EMFILE );
+ SET_STATUS_Failure( VKI_EMFILE );
} else {
if (VG_(clo_track_fds))
VG_(record_fd_open)(tid, RES, VG_(resolve_filename)(RES));
}
}
-PRE(sys_dup2, 0)
+PRE(sys_dup2)
{
PRINT("sys_dup2 ( %d, %d )", ARG1,ARG2);
PRE_REG_READ2(long, "dup2", unsigned int, oldfd, unsigned int, newfd);
if (!VG_(fd_allowed)(ARG2, "dup2", tid, True))
- SET_RESULT( -VKI_EBADF );
+ SET_STATUS_Failure( VKI_EBADF );
}
POST(sys_dup2)
{
+ vg_assert(SUCCESS);
if (VG_(clo_track_fds))
VG_(record_fd_open)(tid, RES, VG_(resolve_filename)(RES));
}
-PRE(sys_fchdir, 0)
-{
- PRINT("sys_fchdir ( %d )", ARG1);
- PRE_REG_READ1(long, "fchdir", unsigned int, fd);
-}
-
-PRE(sys_fchown16, 0)
-{
- PRINT("sys_fchown16 ( %d, %d, %d )", ARG1,ARG2,ARG3);
- PRE_REG_READ3(long, "fchown16",
- unsigned int, fd, vki_old_uid_t, owner, vki_old_gid_t, group);
-}
-
-PRE(sys_fchown, 0)
-{
- PRINT("sys_fchown ( %d, %d, %d )", ARG1,ARG2,ARG3);
- PRE_REG_READ3(long, "fchown",
- unsigned int, fd, vki_uid_t, owner, vki_gid_t, group);
-}
-
-PRE(sys_fchmod, 0)
-{
- PRINT("sys_fchmod ( %d, %d )", ARG1,ARG2);
- PRE_REG_READ2(long, "fchmod", unsigned int, fildes, vki_mode_t, mode);
-}
-
-PRE(sys_fcntl, 0)
-{
- switch (ARG2) {
- // These ones ignore ARG3.
- case VKI_F_GETFD:
- case VKI_F_GETFL:
- case VKI_F_GETOWN:
- case VKI_F_SETOWN:
- case VKI_F_GETSIG:
- case VKI_F_SETSIG:
- case VKI_F_GETLEASE:
- PRINT("sys_fcntl ( %d, %d )", ARG1,ARG2);
- PRE_REG_READ2(long, "fcntl", unsigned int, fd, unsigned int, cmd);
- break;
-
- // These ones use ARG3 as "arg".
- case VKI_F_DUPFD:
- case VKI_F_SETFD:
- case VKI_F_SETFL:
- case VKI_F_SETLEASE:
- case VKI_F_NOTIFY:
- PRINT("sys_fcntl[ARG3=='arg'] ( %d, %d, %d )", ARG1,ARG2,ARG3);
- PRE_REG_READ3(long, "fcntl",
- unsigned int, fd, unsigned int, cmd, unsigned long, arg);
- break;
-
- // These ones use ARG3 as "lock".
- case VKI_F_GETLK:
- case VKI_F_SETLK:
- case VKI_F_SETLKW:
-#ifndef __amd64__
- case VKI_F_GETLK64:
- case VKI_F_SETLK64:
- case VKI_F_SETLKW64:
-#else
-#endif
- PRINT("sys_fcntl[ARG3=='lock'] ( %d, %d, %p )", ARG1,ARG2,ARG3);
- PRE_REG_READ3(long, "fcntl",
- unsigned int, fd, unsigned int, cmd,
- struct flock64 *, lock);
- break;
- }
-
- //if (ARG2 == VKI_F_SETLKW)
- // tst->sys_flags |= MayBlock;
-}
-
-POST(sys_fcntl)
-{
- if (ARG2 == VKI_F_DUPFD) {
- if (!VG_(fd_allowed)(RES, "fcntl(DUPFD)", tid, True)) {
- VG_(close)(RES);
- SET_RESULT( -VKI_EMFILE );
- } else {
- if (VG_(clo_track_fds))
- VG_(record_fd_open)(tid, RES, VG_(resolve_filename)(RES));
- }
- }
-}
+//zz PRE(sys_fchdir, 0)
+//zz {
+//zz PRINT("sys_fchdir ( %d )", ARG1);
+//zz PRE_REG_READ1(long, "fchdir", unsigned int, fd);
+//zz }
+//zz
+//zz PRE(sys_fchown16, 0)
+//zz {
+//zz PRINT("sys_fchown16 ( %d, %d, %d )", ARG1,ARG2,ARG3);
+//zz PRE_REG_READ3(long, "fchown16",
+//zz unsigned int, fd, vki_old_uid_t, owner, vki_old_gid_t, group);
+//zz }
+//zz
+//zz PRE(sys_fchown, 0)
+//zz {
+//zz PRINT("sys_fchown ( %d, %d, %d )", ARG1,ARG2,ARG3);
+//zz PRE_REG_READ3(long, "fchown",
+//zz unsigned int, fd, vki_uid_t, owner, vki_gid_t, group);
+//zz }
+//zz
+//zz PRE(sys_fchmod, 0)
+//zz {
+//zz PRINT("sys_fchmod ( %d, %d )", ARG1,ARG2);
+//zz PRE_REG_READ2(long, "fchmod", unsigned int, fildes, vki_mode_t, mode);
+//zz }
+//zz
+//zz PRE(sys_fcntl, 0)
+//zz {
+//zz switch (ARG2) {
+//zz // These ones ignore ARG3.
+//zz case VKI_F_GETFD:
+//zz case VKI_F_GETFL:
+//zz case VKI_F_GETOWN:
+//zz case VKI_F_SETOWN:
+//zz case VKI_F_GETSIG:
+//zz case VKI_F_SETSIG:
+//zz case VKI_F_GETLEASE:
+//zz PRINT("sys_fcntl ( %d, %d )", ARG1,ARG2);
+//zz PRE_REG_READ2(long, "fcntl", unsigned int, fd, unsigned int, cmd);
+//zz break;
+//zz
+//zz // These ones use ARG3 as "arg".
+//zz case VKI_F_DUPFD:
+//zz case VKI_F_SETFD:
+//zz case VKI_F_SETFL:
+//zz case VKI_F_SETLEASE:
+//zz case VKI_F_NOTIFY:
+//zz PRINT("sys_fcntl[ARG3=='arg'] ( %d, %d, %d )", ARG1,ARG2,ARG3);
+//zz PRE_REG_READ3(long, "fcntl",
+//zz unsigned int, fd, unsigned int, cmd, unsigned long, arg);
+//zz break;
+//zz
+//zz // These ones use ARG3 as "lock".
+//zz case VKI_F_GETLK:
+//zz case VKI_F_SETLK:
+//zz case VKI_F_SETLKW:
+//zz #ifndef __amd64__
+//zz case VKI_F_GETLK64:
+//zz case VKI_F_SETLK64:
+//zz case VKI_F_SETLKW64:
+//zz #else
+//zz #endif
+//zz PRINT("sys_fcntl[ARG3=='lock'] ( %d, %d, %p )", ARG1,ARG2,ARG3);
+//zz PRE_REG_READ3(long, "fcntl",
+//zz unsigned int, fd, unsigned int, cmd,
+//zz struct flock64 *, lock);
+//zz break;
+//zz }
+//zz
+//zz //if (ARG2 == VKI_F_SETLKW)
+//zz // tst->sys_flags |= SfMayBlock;
+//zz }
+//zz
+//zz POST(sys_fcntl)
+//zz {
+//zz if (ARG2 == VKI_F_DUPFD) {
+//zz if (!VG_(fd_allowed)(RES, "fcntl(DUPFD)", tid, True)) {
+//zz VG_(close)(RES);
+//zz SET_STATUS_( -VKI_EMFILE );
+//zz } else {
+//zz if (VG_(clo_track_fds))
+//zz VG_(record_fd_open)(tid, RES, VG_(resolve_filename)(RES));
+//zz }
+//zz }
+//zz }
// XXX: wrapper only suitable for 32-bit systems
-PRE(sys_fcntl64, 0)
+PRE(sys_fcntl64)
{
switch (ARG2) {
// These ones ignore ARG3.
@@ -2710,11 +2634,11 @@ PRE(sys_fcntl64, 0)
case VKI_F_GETLK:
case VKI_F_SETLK:
case VKI_F_SETLKW:
-#ifndef __amd64__
+# if defined(VGP_amd64_linux)
case VKI_F_GETLK64:
case VKI_F_SETLK64:
case VKI_F_SETLKW64:
-#endif
+# endif
PRINT("sys_fcntl64[ARG3=='lock'] ( %d, %d, %p )", ARG1,ARG2,ARG3);
PRE_REG_READ3(long, "fcntl64",
unsigned int, fd, unsigned int, cmd,
@@ -2722,45 +2646,47 @@ PRE(sys_fcntl64, 0)
break;
}
-#ifndef __amd64__
+# if defined(VGP_amd64_linux)
//if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64)
- // tst->sys_flags |= MayBlock;
-#else
+ // tst->sys_flags |= SfMayBlock;
+# else
//if (ARG2 == VKI_F_SETLKW)
- // tst->sys_flags |= MayBlock;
-#endif
+ // tst->sys_flags |= SfMayBlock;
+# endif
}
POST(sys_fcntl64)
{
+ vg_assert(SUCCESS);
if (ARG2 == VKI_F_DUPFD) {
if (!VG_(fd_allowed)(RES, "fcntl64(DUPFD)", tid, True)) {
VG_(close)(RES);
- SET_RESULT( -VKI_EMFILE );
+ SET_STATUS_Failure( VKI_EMFILE );
} else {
if (VG_(clo_track_fds))
- VG_(record_fd_open)(tid, RES, VG_(resolve_filename)(RES));
+ VG_(record_fd_open)(tid, RES,
+ VG_(resolve_filename)(RES));
}
}
}
-PRE(sys_newfstat, 0)
-{
- PRINT("sys_newfstat ( %d, %p )", ARG1,ARG2);
- PRE_REG_READ2(long, "fstat", unsigned int, fd, struct stat *, buf);
- PRE_MEM_WRITE( "fstat(buf)", ARG2, sizeof(struct vki_stat) );
-}
-
-POST(sys_newfstat)
-{
- POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
-}
+//zz PRE(sys_newfstat, 0)
+//zz {
+//zz PRINT("sys_newfstat ( %d, %p )", ARG1,ARG2);
+//zz PRE_REG_READ2(long, "fstat", unsigned int, fd, struct stat *, buf);
+//zz PRE_MEM_WRITE( "fstat(buf)", ARG2, sizeof(struct vki_stat) );
+//zz }
+//zz
+//zz POST(sys_newfstat)
+//zz {
+//zz POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
+//zz }
static vki_sigset_t fork_saved_mask;
// In Linux, the sys_fork() function varies across architectures, but we
// ignore the various args it gets, and so it looks arch-neutral. Hmm.
-PRE(sys_fork, 0)
+PRE(sys_fork)
{
vki_sigset_t mask;
@@ -2774,14 +2700,16 @@ PRE(sys_fork, 0)
VG_(do_atfork_pre)(tid);
- SET_RESULT(VG_(do_syscall0)(__NR_fork));
+ SET_STATUS_from_SysRes( VG_(do_syscall0)(__NR_fork) );
- if (RES == 0) {
+ if (SUCCESS && RES == 0) {
VG_(do_atfork_child)(tid);
/* restore signal mask */
VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
- } else if (RES > 0) {
+ }
+ else
+ if (SUCCESS && RES > 0) {
PRINT(" fork: process %d created child %d\n", VG_(getpid)(), RES);
VG_(do_atfork_parent)(tid);
@@ -2791,57 +2719,58 @@ PRE(sys_fork, 0)
}
}
-PRE(sys_ftruncate, MayBlock)
-{
- PRINT("sys_ftruncate ( %d, %lld )", ARG1,(ULong)ARG2);
- PRE_REG_READ2(long, "ftruncate", unsigned int, fd, unsigned long, length);
-}
-
-PRE(sys_truncate, MayBlock)
-{
- PRINT("sys_truncate ( %p(%s), %d )", ARG1,ARG1,ARG2);
- PRE_REG_READ2(long, "truncate",
- const char *, path, unsigned long, length);
- PRE_MEM_RASCIIZ( "truncate(path)", ARG1 );
-}
-
-// XXX: this wrapper is only suitable for 32-bit platforms
-PRE(sys_ftruncate64, MayBlock)
-{
- PRINT("sys_ftruncate64 ( %d, %lld )", ARG1, LOHI64(ARG2,ARG3));
- PRE_REG_READ3(long, "ftruncate64",
- unsigned int, fd,
- vki_u32, length_low32, vki_u32, length_high32);
-}
-
-// XXX: this wrapper is only suitable for 32-bit platforms
-PRE(sys_truncate64, MayBlock)
-{
- PRINT("sys_truncate64 ( %p, %lld )", ARG1, LOHI64(ARG2, ARG3));
- PRE_REG_READ3(long, "truncate64",
- const char *, path,
- vki_u32, length_low32, vki_u32, length_high32);
- PRE_MEM_RASCIIZ( "truncate64(path)", ARG1 );
-}
-
-
-PRE(sys_getdents, MayBlock)
-{
- PRINT("sys_getdents ( %d, %p, %d )", ARG1,ARG2,ARG3);
- PRE_REG_READ3(long, "getdents",
- unsigned int, fd, struct linux_dirent *, dirp,
- unsigned int, count);
- PRE_MEM_WRITE( "getdents(dirp)", ARG2, ARG3 );
-}
-
-POST(sys_getdents)
-{
- if (RES > 0)
- POST_MEM_WRITE( ARG2, RES );
-}
-
-PRE(sys_getdents64, MayBlock)
-{
+//zz PRE(sys_ftruncate, SfMayBlock)
+//zz {
+//zz PRINT("sys_ftruncate ( %d, %lld )", ARG1,(ULong)ARG2);
+//zz PRE_REG_READ2(long, "ftruncate", unsigned int, fd, unsigned long, length);
+//zz }
+//zz
+//zz PRE(sys_truncate, SfMayBlock)
+//zz {
+//zz PRINT("sys_truncate ( %p(%s), %d )", ARG1,ARG1,ARG2);
+//zz PRE_REG_READ2(long, "truncate",
+//zz const char *, path, unsigned long, length);
+//zz PRE_MEM_RASCIIZ( "truncate(path)", ARG1 );
+//zz }
+//zz
+//zz // XXX: this wrapper is only suitable for 32-bit platforms
+//zz PRE(sys_ftruncate64, SfMayBlock)
+//zz {
+//zz PRINT("sys_ftruncate64 ( %d, %lld )", ARG1, LOHI64(ARG2,ARG3));
+//zz PRE_REG_READ3(long, "ftruncate64",
+//zz unsigned int, fd,
+//zz vki_u32, length_low32, vki_u32, length_high32);
+//zz }
+//zz
+//zz // XXX: this wrapper is only suitable for 32-bit platforms
+//zz PRE(sys_truncate64, SfMayBlock)
+//zz {
+//zz PRINT("sys_truncate64 ( %p, %lld )", ARG1, LOHI64(ARG2, ARG3));
+//zz PRE_REG_READ3(long, "truncate64",
+//zz const char *, path,
+//zz vki_u32, length_low32, vki_u32, length_high32);
+//zz PRE_MEM_RASCIIZ( "truncate64(path)", ARG1 );
+//zz }
+//zz
+//zz
+//zz PRE(sys_getdents, SfMayBlock)
+//zz {
+//zz PRINT("sys_getdents ( %d, %p, %d )", ARG1,ARG2,ARG3);
+//zz PRE_REG_READ3(long, "getdents",
+//zz unsigned int, fd, struct linux_dirent *, dirp,
+//zz unsigned int, count);
+//zz PRE_MEM_WRITE( "getdents(dirp)", ARG2, ARG3 );
+//zz }
+//zz
+//zz POST(sys_getdents)
+//zz {
+//zz if (RES > 0)
+//zz POST_MEM_WRITE( ARG2, RES );
+//zz }
+
+PRE(sys_getdents64)
+{
+ *flags |= SfMayBlock;
PRINT("sys_getdents64 ( %d, %p, %d )",ARG1,ARG2,ARG3);
PRE_REG_READ3(long, "getdents64",
unsigned int, fd, struct linux_dirent64 *, dirp,
@@ -2851,39 +2780,40 @@ PRE(sys_getdents64, MayBlock)
POST(sys_getdents64)
{
+ vg_assert(SUCCESS);
if (RES > 0)
POST_MEM_WRITE( ARG2, RES );
}
-PRE(sys_getgroups16, 0)
-{
- PRINT("sys_getgroups16 ( %d, %p )", ARG1, ARG2);
- PRE_REG_READ2(long, "getgroups16", int, size, vki_old_gid_t *, list);
- if (ARG1 > 0)
- PRE_MEM_WRITE( "getgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
-}
-
-POST(sys_getgroups16)
-{
- if (ARG1 > 0 && RES > 0)
- POST_MEM_WRITE( ARG2, RES * sizeof(vki_old_gid_t) );
-}
-
-PRE(sys_getgroups, 0)
-{
- PRINT("sys_getgroups ( %d, %p )", ARG1, ARG2);
- PRE_REG_READ2(long, "getgroups", int, size, vki_gid_t *, list);
- if (ARG1 > 0)
- PRE_MEM_WRITE( "getgroups(list)", ARG2, ARG1 * sizeof(vki_gid_t) );
-}
-
-POST(sys_getgroups)
-{
- if (ARG1 > 0 && RES > 0)
- POST_MEM_WRITE( ARG2, RES * sizeof(vki_gid_t) );
-}
-
-PRE(sys_getcwd, 0)
+//zz PRE(sys_getgroups16, 0)
+//zz {
+//zz PRINT("sys_getgroups16 ( %d, %p )", ARG1, ARG2);
+//zz PRE_REG_READ2(long, "getgroups16", int, size, vki_old_gid_t *, list);
+//zz if (ARG1 > 0)
+//zz PRE_MEM_WRITE( "getgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
+//zz }
+//zz
+//zz POST(sys_getgroups16)
+//zz {
+//zz if (ARG1 > 0 && RES > 0)
+//zz POST_MEM_WRITE( ARG2, RES * sizeof(vki_old_gid_t) );
+//zz }
+//zz
+//zz PRE(sys_getgroups, 0)
+//zz {
+//zz PRINT("sys_getgroups ( %d, %p )", ARG1, ARG2);
+//zz PRE_REG_READ2(long, "getgroups", int, size, vki_gid_t *, list);
+//zz if (ARG1 > 0)
+//zz PRE_MEM_WRITE( "getgroups(list)", ARG2, ARG1 * sizeof(vki_gid_t) );
+//zz }
+//zz
+//zz POST(sys_getgroups)
+//zz {
+//zz if (ARG1 > 0 && RES > 0)
+//zz POST_MEM_WRITE( ARG2, RES * sizeof(vki_gid_t) );
+//zz }
+
+PRE(sys_getcwd)
{
// Note that the kernel version of getcwd() behaves quite differently to
// the glibc one.
@@ -2894,65 +2824,66 @@ PRE(sys_getcwd, 0)
POST(sys_getcwd)
{
+ vg_assert(SUCCESS);
if (RES != (Addr)NULL)
POST_MEM_WRITE( ARG1, RES );
}
-PRE(sys_geteuid16, 0)
+PRE(sys_geteuid16)
{
PRINT("sys_geteuid16 ( )");
PRE_REG_READ0(long, "geteuid16");
}
-PRE(sys_geteuid, 0)
+PRE(sys_geteuid)
{
PRINT("sys_geteuid ( )");
PRE_REG_READ0(long, "geteuid");
}
-PRE(sys_getegid16, 0)
-{
- PRINT("sys_getegid16 ( )");
- PRE_REG_READ0(long, "getegid16");
-}
-
-PRE(sys_getegid, 0)
-{
- PRINT("sys_getegid ( )");
- PRE_REG_READ0(long, "getegid");
-}
-
-PRE(sys_getgid16, 0)
-{
- PRINT("sys_getgid16 ( )");
- PRE_REG_READ0(long, "getgid16");
-}
-
-PRE(sys_getgid, 0)
-{
- PRINT("sys_getgid ( )");
- PRE_REG_READ0(long, "getgid");
-}
-
-PRE(sys_getpid, 0)
+//zz PRE(sys_getegid16, 0)
+//zz {
+//zz PRINT("sys_getegid16 ( )");
+//zz PRE_REG_READ0(long, "getegid16");
+//zz }
+//zz
+//zz PRE(sys_getegid, 0)
+//zz {
+//zz PRINT("sys_getegid ( )");
+//zz PRE_REG_READ0(long, "getegid");
+//zz }
+//zz
+//zz PRE(sys_getgid16, 0)
+//zz {
+//zz PRINT("sys_getgid16 ( )");
+//zz PRE_REG_READ0(long, "getgid16");
+//zz }
+//zz
+//zz PRE(sys_getgid, 0)
+//zz {
+//zz PRINT("sys_getgid ( )");
+//zz PRE_REG_READ0(long, "getgid");
+//zz }
+
+PRE(sys_getpid)
{
PRINT("sys_getpid ()");
PRE_REG_READ0(long, "getpid");
}
-PRE(sys_getpgid, 0)
-{
- PRINT("sys_getpgid ( %d )", ARG1);
- PRE_REG_READ1(long, "getpgid", vki_pid_t, pid);
-}
-
-PRE(sys_getpgrp, 0)
-{
- PRINT("sys_getpgrp ()");
- PRE_REG_READ0(long, "getpgrp");
-}
+//zz PRE(sys_getpgid, 0)
+//zz {
+//zz PRINT("sys_getpgid ( %d )", ARG1);
+//zz PRE_REG_READ1(long, "getpgid", vki_pid_t, pid);
+//zz }
+//zz
+//zz PRE(sys_getpgrp, 0)
+//zz {
+//zz PRINT("sys_getpgrp ()");
+//zz PRE_REG_READ0(long, "getpgrp");
+//zz }
-PRE(sys_getppid, 0)
+PRE(sys_getppid)
{
PRINT("sys_getppid ()");
PRE_REG_READ0(long, "getppid");
@@ -2978,20 +2909,20 @@ static void common_post_getrlimit(ThreadId tid, UWord a1, UWord a2)
}
}
-PRE(sys_old_getrlimit, 0)
-{
- PRINT("sys_old_getrlimit ( %d, %p )", ARG1,ARG2);
- PRE_REG_READ2(long, "old_getrlimit",
- unsigned int, resource, struct rlimit *, rlim);
- PRE_MEM_WRITE( "old_getrlimit(rlim)", ARG2, sizeof(struct vki_rlimit) );
-}
+//zz PRE(sys_old_getrlimit, 0)
+//zz {
+//zz PRINT("sys_old_getrlimit ( %d, %p )", ARG1,ARG2);
+//zz PRE_REG_READ2(long, "old_getrlimit",
+//zz unsigned int, resource, struct rlimit *, rlim);
+//zz PRE_MEM_WRITE( "old_getrlimit(rlim)", ARG2, sizeof(struct vki_rlimit) );
+//zz }
+//zz
+//zz POST(sys_old_getrlimit)
+//zz {
+//zz common_post_getrlimit(tid, ARG1, ARG2);
+//zz }
-POST(sys_old_getrlimit)
-{
- common_post_getrlimit(tid, ARG1, ARG2);
-}
-
-PRE(sys_getrlimit, 0)
+PRE(sys_getrlimit)
{
PRINT("sys_getrlimit ( %d, %p )", ARG1,ARG2);
PRE_REG_READ2(long, "getrlimit",
@@ -3004,21 +2935,21 @@ POST(sys_getrlimit)
common_post_getrlimit(tid, ARG1, ARG2);
}
-PRE(sys_getrusage, 0)
-{
- /* int getrusage (int who, struct rusage *usage); */
- PRINT("sys_getrusage ( %d, %p )", ARG1,ARG2);
- PRE_REG_READ2(long, "getrusage", int, who, struct rusage *, usage);
- PRE_MEM_WRITE( "getrusage(usage)", ARG2, sizeof(struct vki_rusage) );
-}
-
-POST(sys_getrusage)
-{
- if (RES == 0)
- POST_MEM_WRITE( ARG2, sizeof(struct vki_rusage) );
-}
+//zz PRE(sys_getrusage, 0)
+//zz {
+//zz /* int getrusage (int who, struct rusage *usage); */
+//zz PRINT("sys_getrusage ( %d, %p )", ARG1,ARG2);
+//zz PRE_REG_READ2(long, "getrusage", int, who, struct rusage *, usage);
+//zz PRE_MEM_WRITE( "getrusage(usage)", ARG2, sizeof(struct vki_rusage) );
+//zz }
+//zz
+//zz POST(sys_getrusage)
+//zz {
+//zz if (RES == 0)
+//zz POST_MEM_WRITE( ARG2, sizeof(struct vki_rusage) );
+//zz }
-PRE(sys_gettimeofday, 0)
+PRE(sys_gettimeofday)
{
PRINT("sys_gettimeofday ( %p, %p )", ARG1,ARG2);
PRE_REG_READ2(long, "gettimeofday",
@@ -3030,6 +2961,7 @@ PRE(sys_gettimeofday, 0)
POST(sys_gettimeofday)
{
+ vg_assert(SUCCESS);
if (RES == 0) {
POST_MEM_WRITE( ARG1, sizeof(struct vki_timeval) );
if (ARG2 != 0)
@@ -3037,33 +2969,34 @@ POST(sys_gettimeofday)
}
}
-PRE(sys_settimeofday, 0)
-{
- PRINT("sys_settimeofday ( %p, %p )", ARG1,ARG2);
- PRE_REG_READ2(long, "settimeofday",
- struct timeval *, tv, struct timezone *, tz);
- PRE_MEM_READ( "settimeofday(tv)", ARG1, sizeof(struct vki_timeval) );
- if (ARG2 != 0) {
- PRE_MEM_READ( "settimeofday(tz)", ARG2, sizeof(struct vki_timezone) );
- /* maybe should warn if tz->tz_dsttime is non-zero? */
- }
-}
+//zz PRE(sys_settimeofday, 0)
+//zz {
+//zz PRINT("sys_settimeofday ( %p, %p )", ARG1,ARG2);
+//zz PRE_REG_READ2(long, "settimeofday",
+//zz struct timeval *, tv, struct timezone *, tz);
+//zz PRE_MEM_READ( "settimeofday(tv)", ARG1, sizeof(struct vki_timeval) );
+//zz if (ARG2 != 0) {
+//zz PRE_MEM_READ( "settimeofday(tz)", ARG2, sizeof(struct vki_timezone) );
+//zz /* maybe should warn if tz->tz_dsttime is non-zero? */
+//zz }
+//zz }
-PRE(sys_getuid16, 0)
+PRE(sys_getuid16)
{
PRINT("sys_getuid16 ( )");
PRE_REG_READ0(long, "getuid16");
}
-PRE(sys_getuid, 0)
+PRE(sys_getuid)
{
PRINT("sys_getuid ( )");
PRE_REG_READ0(long, "getuid");
}
// XXX: I reckon some of these cases must be x86-specific
-PRE(sys_ioctl, MayBlock)
+PRE(sys_ioctl)
{
+ *flags |= SfMayBlock;
PRINT("sys_ioctl ( %d, 0x%x, %p )",ARG1,ARG2,ARG3);
PRE_REG_READ3(long, "ioctl",
unsigned int, fd, unsigned int, request, unsigned long, arg);
@@ -3378,7 +3311,7 @@ PRE(sys_ioctl, MayBlock)
break;
case VKI_SIOCSPGRP:
PRE_MEM_READ( "ioctl(SIOCSPGRP)", ARG3, sizeof(int) );
- //tst->sys_flags &= ~MayBlock;
+ //tst->sys_flags &= ~SfMayBlock;
break;
/* linux/soundcard interface (OSS) */
@@ -3827,6 +3760,7 @@ PRE(sys_ioctl, MayBlock)
POST(sys_ioctl)
{
+ vg_assert(SUCCESS);
switch (ARG2 /* request */) {
case VKI_TCSETS:
case VKI_TCSETSW:
@@ -4323,7 +4257,7 @@ POST(sys_ioctl)
UInt dir = _VKI_IOC_DIR(ARG2);
UInt size = _VKI_IOC_SIZE(ARG2);
if (size > 0 && (dir & _VKI_IOC_READ)
- && RES == 0
+ && RES == 0
&& ARG3 != (Addr)NULL)
POST_MEM_WRITE(ARG3, size);
break;
@@ -4369,7 +4303,8 @@ Bool VG_(do_sigkill)(Int pid, Int tgid)
/* Check to see that the target isn't already exiting. */
if (!VG_(is_exiting)(tid)) {
if (VG_(clo_trace_signals))
- VG_(message)(Vg_DebugMsg, "Thread %d being killed with SIGKILL", tst->tid);
+ VG_(message)(Vg_DebugMsg, "Thread %d being killed with SIGKILL",
+ tst->tid);
tst->exitreason = VgSrc_FatalSig;
tst->os_state.fatalsig = VKI_SIGKILL;
@@ -4381,167 +4316,74 @@ Bool VG_(do_sigkill)(Int pid, Int tgid)
return True;
}
-PRE(sys_kill, Special)
+PRE(sys_kill)
{
/* int kill(pid_t pid, int sig); */
PRINT("sys_kill ( %d, %d )", ARG1,ARG2);
PRE_REG_READ2(long, "kill", int, pid, int, sig);
if (!VG_(client_signal_OK)(ARG2)) {
- SET_RESULT( -VKI_EINVAL );
+ SET_STATUS_Failure( VKI_EINVAL );
return;
}
/* If we're sending SIGKILL, check to see if the target is one of
our threads and handle it specially. */
if (ARG2 == VKI_SIGKILL && VG_(do_sigkill)(ARG1, -1))
- SET_RESULT(0);
+ SET_STATUS_Success(0);
else
- SET_RESULT(VG_(do_syscall2)(SYSNO, ARG1, ARG2));
+ SET_STATUS_from_SysRes( VG_(do_syscall2)(SYSNO, ARG1, ARG2) );
if (VG_(clo_trace_signals))
VG_(message)(Vg_DebugMsg, "kill: sent signal %d to pid %d",
ARG2, ARG1);
- // Check to see if this kill gave us a pending signal
- VG_(poll_signals)(tid);
+
+ /* This kill might have given us a pending signal. Ask for a check once
+ the syscall is done. */
+ *flags |= SfPollAfter;
}
-PRE(sys_link, MayBlock)
+PRE(sys_link)
{
+ *flags |= SfMayBlock;
PRINT("sys_link ( %p, %p)", ARG1, ARG2);
PRE_REG_READ2(long, "link", const char *, oldpath, const char *, newpath);
PRE_MEM_RASCIIZ( "link(oldpath)", ARG1);
PRE_MEM_RASCIIZ( "link(newpath)", ARG2);
}
-PRE(sys_lseek, 0)
+PRE(sys_lseek)
{
PRINT("sys_lseek ( %d, %d, %d )", ARG1,ARG2,ARG3);
PRE_REG_READ3(vki_off_t, "lseek",
unsigned int, fd, vki_off_t, offset, unsigned int, whence);
}
-PRE(sys_newlstat, 0)
-{
- PRINT("sys_newlstat ( %p(%s), %p )", ARG1,ARG1,ARG2);
- PRE_REG_READ2(long, "lstat", char *, file_name, struct stat *, buf);
- PRE_MEM_RASCIIZ( "lstat(file_name)", ARG1 );
- PRE_MEM_WRITE( "lstat(buf)", ARG2, sizeof(struct vki_stat) );
-}
-
-POST(sys_newlstat)
-{
- if (RES == 0) {
- POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
- }
-}
-
-// XXX: this syscall is generic, but not necessarily applicable to every
-// architecture -- I think only to 32-bit archs. We're going to need
-// something like linux/core_os32.h for such things, eventually, I think.
-// --njn
-#ifndef __amd64__
-PRE(sys_lstat64, 0)
-{
- PRINT("sys_lstat64 ( %p(%s), %p )",ARG1,ARG1,ARG2);
- PRE_REG_READ2(long, "lstat64", char *, file_name, struct stat64 *, buf);
- PRE_MEM_RASCIIZ( "lstat64(file_name)", ARG1 );
- PRE_MEM_WRITE( "lstat64(buf)", ARG2, sizeof(struct vki_stat64) );
-}
-
-POST(sys_lstat64)
-{
- if (RES == 0) {
- POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
- }
-}
-#endif
-
-PRE(sys_mkdir, MayBlock)
-{
+//zz PRE(sys_newlstat, 0)
+//zz {
+//zz PRINT("sys_newlstat ( %p(%s), %p )", ARG1,ARG1,ARG2);
+//zz PRE_REG_READ2(long, "lstat", char *, file_name, struct stat *, buf);
+//zz PRE_MEM_RASCIIZ( "lstat(file_name)", ARG1 );
+//zz PRE_MEM_WRITE( "lstat(buf)", ARG2, sizeof(struct vki_stat) );
+//zz }
+//zz
+//zz POST(sys_newlstat)
+//zz {
+//zz if (RES == 0) {
+//zz POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
+//zz }
+//zz }
+
+PRE(sys_mkdir)
+{
+ *flags |= SfMayBlock;
PRINT("sys_mkdir ( %p, %d )", ARG1,ARG2);
PRE_REG_READ2(long, "mkdir", const char *, pathname, int, mode);
PRE_MEM_RASCIIZ( "mkdir(pathname)", ARG1 );
}
-// Nb: this should probably be in m_syscalls/syscalls-x86-linux.c, but it
-// might be required for ARM, and I was too lazy to move it (which would
-// have required making mmap_segment() public).
-PRE(old_mmap, Special)
+PRE(sys_mmap2)
{
- /* struct mmap_arg_struct {
- unsigned long addr;
- unsigned long len;
- unsigned long prot;
- unsigned long flags;
- unsigned long fd;
- unsigned long offset;
- }; */
-#if defined(VGP_x86_linux)
- // do nothing
-#else
- vg_assert2(0, "old_mmap should only be called on x86/Linux");
-#endif
-
- UWord a1, a2, a3, a4, a5, a6;
- UWord *arg_block = (UWord*)(tst->arch.vex.VGP_SYSCALL_ARG1);
-
- PRE_REG_READ1(long, "old_mmap", struct mmap_arg_struct *, args);
- arg_block = (UWord*)(tst->arch.vex.VGP_SYSCALL_ARG1);
- PRE_MEM_READ( "old_mmap(args)", (Addr)arg_block, 6*sizeof(UWord) );\
- a1 = arg_block[0];
- a2 = arg_block[1];
- a3 = arg_block[2];
- a4 = arg_block[3];
- a5 = arg_block[4];
- a6 = arg_block[5];
-
- PRINT("old_mmap ( %p, %llu, %d, %d, %d, %d )",
- a1, (ULong)a2, a3, a4, a5, a6 );
-
- if (a2 == 0) {
- /* SuSV3 says: If len is zero, mmap() shall fail and no mapping
- shall be established. */
- SET_RESULT( -VKI_EINVAL );
- return;
- }
-
- if (/*(a4 & VKI_MAP_FIXED) &&*/ (0 != (a1 & (VKI_PAGE_SIZE-1)))) {
- /* zap any misaligned addresses. */
- SET_RESULT( -VKI_EINVAL );
- return;
- }
-
- if (a4 & VKI_MAP_FIXED) {
- if (!VG_(valid_client_addr)(a1, a2, tid, "old_mmap")) {
- PRINT("old_mmap failing: %p-%p\n", a1, a1+a2);
- SET_RESULT( -VKI_ENOMEM );
- }
- } else {
- Addr a = VG_(find_map_space)(a1, a2, True);
- if (a == 0 && a1 != 0)
- a1 = VG_(find_map_space)(0, a2, True);
- else
- a1 = a;
- if (a1 == 0)
- SET_RESULT( -VKI_ENOMEM );
- else
- a4 |= VKI_MAP_FIXED;
- }
-
- if (RES != -VKI_ENOMEM) {
- Int res = (Int)VG_(mmap_native)((void*)a1, a2, a3, a4, a5, a6);
- SET_RESULT(res);
-
- if (!VG_(is_kerror)(RES)) {
- vg_assert(VG_(valid_client_addr)(RES, a2, tid, "old_mmap"));
- mmap_segment( (Addr)RES, a2, a3, a4, a5, a6 );
- }
- }
-}
-
-PRE(sys_mmap2, 0)
-{
- // Exactly like old_mmap() except:
+ // Exactly like old_mmap() in x86-linux except:
// - all 6 args are passed in regs, rather than in a memory-block.
// - the file offset is specified in pagesize units rather than bytes,
// so that it can be used for files bigger than 2^32 bytes.
@@ -4555,7 +4397,7 @@ PRE(sys_mmap2, 0)
if (ARG2 == 0) {
/* SuSV3 says: If len is zero, mmap() shall fail and no mapping
shall be established. */
- SET_RESULT( -VKI_EINVAL );
+ SET_STATUS_Failure( VKI_EINVAL );
return;
}
@@ -4563,13 +4405,13 @@ PRE(sys_mmap2, 0)
/* zap any misaligned addresses. */
/* SuSV3 says misaligned addresses only cause the MAP_FIXED case
to fail. Here, we catch them all. */
- SET_RESULT( -VKI_EINVAL );
+ SET_STATUS_Failure( VKI_EINVAL );
return;
}
if (ARG4 & VKI_MAP_FIXED) {
if (!VG_(valid_client_addr)(ARG1, ARG2, tid, "mmap2"))
- SET_RESULT( -VKI_ENOMEM );
+ SET_STATUS_Failure( VKI_ENOMEM );
} else {
Addr a = VG_(find_map_space)(ARG1, ARG2, True);
if (a == 0 && ARG1 != 0)
@@ -4577,7 +4419,7 @@ PRE(sys_mmap2, 0)
else
ARG1 = a;
if (ARG1 == 0)
- SET_RESULT( -VKI_ENOMEM );
+ SET_STATUS_Failure( VKI_ENOMEM );
else
ARG4 |= VKI_MAP_FIXED;
}
@@ -4585,19 +4427,20 @@ PRE(sys_mmap2, 0)
POST(sys_mmap2)
{
+ vg_assert(SUCCESS);
vg_assert(VG_(valid_client_addr)(RES, ARG2, tid, "mmap2"));
- mmap_segment( (Addr)RES, ARG2, ARG3, ARG4, ARG5,
- ARG6 * (ULong)VKI_PAGE_SIZE );
+ VG_(mmap_segment)( (Addr)RES, ARG2, ARG3, ARG4, ARG5,
+ ARG6 * (ULong)VKI_PAGE_SIZE );
}
-PRE(sys_mprotect, 0)
+PRE(sys_mprotect)
{
PRINT("sys_mprotect ( %p, %llu, %d )", ARG1,(ULong)ARG2,ARG3);
PRE_REG_READ3(long, "mprotect",
unsigned long, addr, vki_size_t, len, unsigned long, prot);
if (!VG_(valid_client_addr)(ARG1, ARG2, tid, "mprotect"))
- SET_RESULT( -VKI_ENOMEM );
+ SET_STATUS_Failure( VKI_ENOMEM );
}
POST(sys_mprotect)
@@ -4614,13 +4457,14 @@ POST(sys_mprotect)
VG_TRACK( change_mem_mprotect, a, len, rr, ww, xx );
}
-PRE(sys_munmap, 0)
+PRE(sys_munmap)
{
+ if (0) VG_(printf)(" munmap( %p )\n", ARG1);
PRINT("sys_munmap ( %p, %llu )", ARG1,(ULong)ARG2);
PRE_REG_READ2(long, "munmap", unsigned long, start, vki_size_t, length);
if (!VG_(valid_client_addr)(ARG1, ARG2, tid, "munmap"))
- SET_RESULT( -VKI_EINVAL );
+ SET_STATUS_Failure( VKI_EINVAL );
}
POST(sys_munmap)
@@ -4633,22 +4477,23 @@ POST(sys_munmap)
VG_TRACK( die_mem_munmap, a, len );
}
-PRE(sys_mincore, 0)
-{
- PRINT("sys_mincore ( %p, %llu, %p )", ARG1,(ULong)ARG2,ARG3);
- PRE_REG_READ3(long, "mincore",
- unsigned long, start, vki_size_t, length,
- unsigned char *, vec);
- PRE_MEM_WRITE( "mincore(vec)", ARG3, (ARG2 + 4096 - 1) / 4096);
-}
-
-POST(sys_mincore)
-{
- POST_MEM_WRITE( ARG3, (ARG2 + 4096 - 1) / 4096 );
-}
+//zz PRE(sys_mincore, 0)
+//zz {
+//zz PRINT("sys_mincore ( %p, %llu, %p )", ARG1,(ULong)ARG2,ARG3);
+//zz PRE_REG_READ3(long, "mincore",
+//zz unsigned long, start, vki_size_t, length,
+//zz unsigned char *, vec);
+//zz PRE_MEM_WRITE( "mincore(vec)", ARG3, (ARG2 + 4096 - 1) / 4096);
+//zz }
+//zz
+//zz POST(sys_mincore)
+//zz {
+//zz POST_MEM_WRITE( ARG3, (ARG2 + 4096 - 1) / 4096 );
+//zz }
-PRE(sys_nanosleep, MayBlock|PostOnFail)
+PRE(sys_nanosleep)
{
+ *flags |= SfMayBlock|SfPostOnFail;
PRINT("sys_nanosleep ( %p, %p )", ARG1,ARG2);
PRE_REG_READ2(long, "nanosleep",
struct timespec *, req, struct timespec *, rem);
@@ -4659,12 +4504,14 @@ PRE(sys_nanosleep, MayBlock|PostOnFail)
POST(sys_nanosleep)
{
- if (ARG2 != 0 && RES == -VKI_EINTR)
+ vg_assert(SUCCESS || FAILURE);
+ if (ARG2 != 0 && FAILURE && RES_unchecked == VKI_EINTR)
POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
}
-PRE(sys_open, MayBlock)
+PRE(sys_open)
{
+ *flags |= SfMayBlock;
if (ARG2 & VKI_O_CREAT) {
// 3-arg version
PRINT("sys_open ( %p(%s), %d, %d )",ARG1,ARG1,ARG2,ARG3);
@@ -4681,45 +4528,51 @@ PRE(sys_open, MayBlock)
POST(sys_open)
{
+ vg_assert(SUCCESS);
if (!VG_(fd_allowed)(RES, "open", tid, True)) {
VG_(close)(RES);
- SET_RESULT( -VKI_EMFILE );
+ SET_STATUS_Failure( VKI_EMFILE );
} else {
if (VG_(clo_track_fds))
- VG_(record_fd_open)(tid, RES, VG_(arena_strdup)(VG_AR_CORE, (Char*)ARG1));
+ VG_(record_fd_open)(tid, RES,
+ VG_(arena_strdup)(VG_AR_CORE, (Char*)ARG1));
}
}
-PRE(sys_read, MayBlock)
+PRE(sys_read)
{
+ *flags |= SfMayBlock;
PRINT("sys_read ( %d, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
PRE_REG_READ3(ssize_t, "read",
unsigned int, fd, char *, buf, vki_size_t, count);
if (!VG_(fd_allowed)(ARG1, "read", tid, False))
- SET_RESULT( -VKI_EBADF );
+ SET_STATUS_Failure( VKI_EBADF );
else
PRE_MEM_WRITE( "read(buf)", ARG2, ARG3 );
}
POST(sys_read)
{
+ vg_assert(SUCCESS);
POST_MEM_WRITE( ARG2, RES );
}
-PRE(sys_write, MayBlock)
+PRE(sys_write)
{
+ *flags |= SfMayBlock;
PRINT("sys_write ( %d, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
PRE_REG_READ3(ssize_t, "write",
unsigned int, fd, const char *, buf, vki_size_t, count);
if (!VG_(fd_allowed)(ARG1, "write", tid, False))
- SET_RESULT( -VKI_EBADF );
+ SET_STATUS_Failure( VKI_EBADF );
else
PRE_MEM_READ( "write(buf)", ARG2, ARG3 );
}
-PRE(sys_creat, MayBlock)
+PRE(sys_creat)
{
+ *flags |= SfMayBlock;
PRINT("sys_creat ( %p(%s), %d )", ARG1,ARG1,ARG2);
PRE_REG_READ2(long, "creat", const char *, pathname, int, mode);
PRE_MEM_RASCIIZ( "creat(pathname)", ARG1 );
@@ -4727,9 +4580,10 @@ PRE(sys_creat, MayBlock)
POST(sys_creat)
{
+ vg_assert(SUCCESS);
if (!VG_(fd_allowed)(RES, "creat", tid, True)) {
VG_(close)(RES);
- SET_RESULT( -VKI_EMFILE );
+ SET_STATUS_Failure( VKI_EMFILE );
} else {
if (VG_(clo_track_fds))
VG_(record_fd_open)(tid, RES, VG_(arena_strdup)(VG_AR_CORE, (Char*)ARG1));
@@ -4737,7 +4591,7 @@ POST(sys_creat)
}
// XXX: sort of x86-specific
-PRE(sys_pipe, 0)
+PRE(sys_pipe)
{
PRINT("sys_pipe ( %p )", ARG1);
PRE_REG_READ1(int, "pipe", unsigned long *, filedes);
@@ -4752,7 +4606,7 @@ POST(sys_pipe)
!VG_(fd_allowed)(p[1], "pipe", tid, True)) {
VG_(close)(p[0]);
VG_(close)(p[1]);
- SET_RESULT( -VKI_EMFILE );
+ SET_STATUS_Failure( VKI_EMFILE );
} else {
POST_MEM_WRITE( ARG1, 2*sizeof(int) );
if (VG_(clo_track_fds)) {
@@ -4763,7 +4617,7 @@ POST(sys_pipe)
}
// XXX: x86-specific, due to pollfd struct
-PRE(sys_poll, MayBlock)
+PRE(sys_poll)
{
/* struct pollfd {
int fd; -- file descriptor
@@ -4773,6 +4627,7 @@ PRE(sys_poll, MayBlock)
int poll(struct pollfd *ufds, unsigned int nfds, int timeout)
*/
UInt i;
+ *flags |= SfMayBlock;
struct vki_pollfd* ufds = (struct vki_pollfd *)ARG1;
PRINT("sys_poll ( %p, %d, %d )\n", ARG1,ARG2,ARG3);
PRE_REG_READ3(long, "poll",
@@ -4799,9 +4654,9 @@ POST(sys_poll)
}
}
-PRE(sys_readlink, Special)
+PRE(sys_readlink)
{
- int saved = SYSNO;
+ Word saved = SYSNO;
PRINT("sys_readlink ( %p, %p, %llu )", ARG1,ARG2,(ULong)ARG3);
PRE_REG_READ3(long, "readlink",
const char *, path, char *, buf, int, bufsiz);
@@ -4813,33 +4668,36 @@ PRE(sys_readlink, Special)
* /proc/<pid>/exe.
*/
- SET_RESULT( VG_(do_syscall3)(saved, ARG1, ARG2, ARG3));
- if ((Int)RES == -2) {
- char name[25];
+ SET_STATUS_from_SysRes( VG_(do_syscall3)(saved, ARG1, ARG2, ARG3));
+ /* jrs 20050604: where does the magic value 2 come from? It seems
+ like it should be a kernel error value, but we don't know of any
+ such. */
+ if (SWHAT == SsFailure && RES_unchecked == 2) {
+ HChar name[25];
VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
-
if (VG_(strcmp)((Char *)ARG1, name) == 0 ||
VG_(strcmp)((Char *)ARG1, "/proc/self/exe") == 0) {
VG_(sprintf)(name, "/proc/self/fd/%d", VG_(clexecfd));
- SET_RESULT( VG_(do_syscall3)(saved, (UWord)name, ARG2, ARG3));
+ SET_STATUS_from_SysRes( VG_(do_syscall3)(saved, (UWord)name, ARG2, ARG3));
}
}
- if ((Int)RES > 0)
+ if (SUCCESS && RES > 0)
POST_MEM_WRITE( ARG2, RES );
}
-PRE(sys_readv, MayBlock)
+PRE(sys_readv)
{
Int i;
struct vki_iovec * vec;
+ *flags |= SfMayBlock;
PRINT("sys_readv ( %d, %p, %llu )",ARG1,ARG2,(ULong)ARG3);
PRE_REG_READ3(ssize_t, "readv",
unsigned long, fd, const struct iovec *, vector,
unsigned long, count);
if (!VG_(fd_allowed)(ARG1, "readv", tid, False)) {
- SET_RESULT( -VKI_EBADF );
+ SET_STATUS_Failure( VKI_EBADF );
} else {
PRE_MEM_READ( "readv(vector)", ARG2, ARG3 * sizeof(struct vki_iovec) );
@@ -4855,6 +4713,7 @@ PRE(sys_readv, MayBlock)
POST(sys_readv)
{
+ vg_assert(SUCCESS);
if (RES > 0) {
Int i;
struct vki_iovec * vec = (struct vki_iovec *)ARG2;
@@ -4871,7 +4730,7 @@ POST(sys_readv)
}
}
-PRE(sys_rename, 0)
+PRE(sys_rename)
{
PRINT("sys_rename ( %p, %p )", ARG1, ARG2 );
PRE_REG_READ2(long, "rename", const char *, oldpath, const char *, newpath);
@@ -4879,41 +4738,42 @@ PRE(sys_rename, 0)
PRE_MEM_RASCIIZ( "rename(newpath)", ARG2 );
}
-PRE(sys_rmdir, MayBlock)
-{
- PRINT("sys_rmdir ( %p )", ARG1);
- PRE_REG_READ1(long, "rmdir", const char *, pathname);
- PRE_MEM_RASCIIZ( "rmdir(pathname)", ARG1 );
-}
-
-PRE(sys_sched_setparam, 0)
-{
- PRINT("sched_setparam ( %d, %p )", ARG1, ARG2 );
- PRE_REG_READ2(long, "sched_setparam",
- vki_pid_t, pid, struct sched_param *, p);
- PRE_MEM_READ( "sched_setparam(p)", ARG2, sizeof(struct vki_sched_param) );
-}
-
-POST(sys_sched_setparam)
-{
- POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
-}
-
-PRE(sys_sched_getparam, 0)
-{
- PRINT("sched_getparam ( %d, %p )", ARG1, ARG2 );
- PRE_REG_READ2(long, "sched_getparam",
- vki_pid_t, pid, struct sched_param *, p);
- PRE_MEM_WRITE( "sched_getparam(p)", ARG2, sizeof(struct vki_sched_param) );
-}
-
-POST(sys_sched_getparam)
-{
- POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
-}
-
-PRE(sys_select, MayBlock)
-{
+//zz PRE(sys_rmdir, SfMayBlock)
+//zz {
+//zz PRINT("sys_rmdir ( %p )", ARG1);
+//zz PRE_REG_READ1(long, "rmdir", const char *, pathname);
+//zz PRE_MEM_RASCIIZ( "rmdir(pathname)", ARG1 );
+//zz }
+//zz
+//zz PRE(sys_sched_setparam, 0)
+//zz {
+//zz PRINT("sched_setparam ( %d, %p )", ARG1, ARG2 );
+//zz PRE_REG_READ2(long, "sched_setparam",
+//zz vki_pid_t, pid, struct sched_param *, p);
+//zz PRE_MEM_READ( "sched_setparam(p)", ARG2, sizeof(struct vki_sched_param) );
+//zz }
+//zz
+//zz POST(sys_sched_setparam)
+//zz {
+//zz POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
+//zz }
+//zz
+//zz PRE(sys_sched_getparam, 0)
+//zz {
+//zz PRINT("sched_getparam ( %d, %p )", ARG1, ARG2 );
+//zz PRE_REG_READ2(long, "sched_getparam",
+//zz vki_pid_t, pid, struct sched_param *, p);
+//zz PRE_MEM_WRITE( "sched_getparam(p)", ARG2, sizeof(struct vki_sched_param) );
+//zz }
+//zz
+//zz POST(sys_sched_getparam)
+//zz {
+//zz POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
+//zz }
+
+PRE(sys_select)
+{
+ *flags |= SfMayBlock;
PRINT("sys_select ( %d, %p, %p, %p, %p )", ARG1,ARG2,ARG3,ARG4,ARG5);
PRE_REG_READ5(long, "select",
int, n, vki_fd_set *, readfds, vki_fd_set *, writefds,
@@ -4932,65 +4792,65 @@ PRE(sys_select, MayBlock)
PRE_MEM_READ( "select(timeout)", ARG5, sizeof(struct vki_timeval) );
}
-PRE(sys_setgid16, 0)
-{
- PRINT("sys_setgid16 ( %d )", ARG1);
- PRE_REG_READ1(long, "setgid16", vki_old_gid_t, gid);
-}
-
-PRE(sys_setgid, 0)
-{
- PRINT("sys_setgid ( %d )", ARG1);
- PRE_REG_READ1(long, "setgid", vki_gid_t, gid);
-}
-
-PRE(sys_setsid, 0)
-{
- PRINT("sys_setsid ( )");
- PRE_REG_READ0(long, "setsid");
-}
-
-PRE(sys_setgroups16, 0)
-{
- PRINT("sys_setgroups16 ( %llu, %p )", (ULong)ARG1, ARG2);
- PRE_REG_READ2(long, "setgroups16", int, size, vki_old_gid_t *, list);
- if (ARG1 > 0)
- PRE_MEM_READ( "setgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
-}
-
-PRE(sys_setgroups, 0)
-{
- PRINT("setgroups ( %llu, %p )", (ULong)ARG1, ARG2);
- PRE_REG_READ2(long, "setgroups", int, size, vki_gid_t *, list);
- if (ARG1 > 0)
- PRE_MEM_READ( "setgroups(list)", ARG2, ARG1 * sizeof(vki_gid_t) );
-}
-
-PRE(sys_setpgid, 0)
-{
- PRINT("setpgid ( %d, %d )", ARG1, ARG2);
- PRE_REG_READ2(long, "setpgid", vki_pid_t, pid, vki_pid_t, pgid);
-}
-
-PRE(sys_setregid, 0)
-{
- PRINT("sys_setregid ( %d, %d )", ARG1, ARG2);
- PRE_REG_READ2(long, "setregid", vki_gid_t, rgid, vki_gid_t, egid);
-}
-
-PRE(sys_setreuid16, 0)
-{
- PRINT("setreuid16 ( 0x%x, 0x%x )", ARG1, ARG2);
- PRE_REG_READ2(long, "setreuid16", vki_old_uid_t, ruid, vki_old_uid_t, euid);
-}
-
-PRE(sys_setreuid, 0)
-{
- PRINT("sys_setreuid ( 0x%x, 0x%x )", ARG1, ARG2);
- PRE_REG_READ2(long, "setreuid", vki_uid_t, ruid, vki_uid_t, euid);
-}
-
-PRE(sys_setrlimit, 0)
+//zz PRE(sys_setgid16, 0)
+//zz {
+//zz PRINT("sys_setgid16 ( %d )", ARG1);
+//zz PRE_REG_READ1(long, "setgid16", vki_old_gid_t, gid);
+//zz }
+//zz
+//zz PRE(sys_setgid, 0)
+//zz {
+//zz PRINT("sys_setgid ( %d )", ARG1);
+//zz PRE_REG_READ1(long, "setgid", vki_gid_t, gid);
+//zz }
+//zz
+//zz PRE(sys_setsid, 0)
+//zz {
+//zz PRINT("sys_setsid ( )");
+//zz PRE_REG_READ0(long, "setsid");
+//zz }
+//zz
+//zz PRE(sys_setgroups16, 0)
+//zz {
+//zz PRINT("sys_setgroups16 ( %llu, %p )", (ULong)ARG1, ARG2);
+//zz PRE_REG_READ2(long, "setgroups16", int, size, vki_old_gid_t *, list);
+//zz if (ARG1 > 0)
+//zz PRE_MEM_READ( "setgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
+//zz }
+//zz
+//zz PRE(sys_setgroups, 0)
+//zz {
+//zz PRINT("setgroups ( %llu, %p )", (ULong)ARG1, ARG2);
+//zz PRE_REG_READ2(long, "setgroups", int, size, vki_gid_t *, list);
+//zz if (ARG1 > 0)
+//zz PRE_MEM_READ( "setgroups(list)", ARG2, ARG1 * sizeof(vki_gid_t) );
+//zz }
+//zz
+//zz PRE(sys_setpgid, 0)
+//zz {
+//zz PRINT("setpgid ( %d, %d )", ARG1, ARG2);
+//zz PRE_REG_READ2(long, "setpgid", vki_pid_t, pid, vki_pid_t, pgid);
+//zz }
+//zz
+//zz PRE(sys_setregid, 0)
+//zz {
+//zz PRINT("sys_setregid ( %d, %d )", ARG1, ARG2);
+//zz PRE_REG_READ2(long, "setregid", vki_gid_t, rgid, vki_gid_t, egid);
+//zz }
+//zz
+//zz PRE(sys_setreuid16, 0)
+//zz {
+//zz PRINT("setreuid16 ( 0x%x, 0x%x )", ARG1, ARG2);
+//zz PRE_REG_READ2(long, "setreuid16", vki_old_uid_t, ruid, vki_old_uid_t, euid);
+//zz }
+//zz
+//zz PRE(sys_setreuid, 0)
+//zz {
+//zz PRINT("sys_setreuid ( 0x%x, 0x%x )", ARG1, ARG2);
+//zz PRE_REG_READ2(long, "setreuid", vki_uid_t, ruid, vki_uid_t, euid);
+//zz }
+
+PRE(sys_setrlimit)
{
PRINT("sys_setrlimit ( %d, %p )", ARG1,ARG2);
PRE_REG_READ2(long, "setrlimit",
@@ -5000,372 +4860,97 @@ PRE(sys_setrlimit, 0)
if (ARG1 == VKI_RLIMIT_NOFILE) {
if (((struct vki_rlimit *)ARG2)->rlim_cur > VG_(fd_hard_limit) ||
((struct vki_rlimit *)ARG2)->rlim_max != VG_(fd_hard_limit)) {
- SET_RESULT( -VKI_EPERM );
+ SET_STATUS_Failure( VKI_EPERM );
}
else {
VG_(fd_soft_limit) = ((struct vki_rlimit *)ARG2)->rlim_cur;
- SET_RESULT( 0 );
+ SET_STATUS_Success( 0 );
}
}
else if (ARG1 == VKI_RLIMIT_DATA) {
if (((struct vki_rlimit *)ARG2)->rlim_cur > ((struct vki_rlimit *)ARG2)->rlim_max ||
((struct vki_rlimit *)ARG2)->rlim_max > ((struct vki_rlimit *)ARG2)->rlim_max) {
- SET_RESULT( -VKI_EPERM );
+ SET_STATUS_Failure( VKI_EPERM );
}
else {
VG_(client_rlimit_data) = *(struct vki_rlimit *)ARG2;
- SET_RESULT( 0 );
+ SET_STATUS_Success( 0 );
}
}
else if (ARG1 == VKI_RLIMIT_STACK && tid == 1) {
if (((struct vki_rlimit *)ARG2)->rlim_cur > ((struct vki_rlimit *)ARG2)->rlim_max ||
((struct vki_rlimit *)ARG2)->rlim_max > ((struct vki_rlimit *)ARG2)->rlim_max) {
- SET_RESULT( -VKI_EPERM );
+ SET_STATUS_Failure( VKI_EPERM );
}
else {
- VG_(threads)[tid].client_stack_szB = ((struct vki_rlimit *)ARG2)->rlim_cur;
+ VG_(threads)[tid].client_stack_szB = ((struct vki_rlimit *)ARG2)->rlim_cur;
VG_(client_rlimit_stack) = *(struct vki_rlimit *)ARG2;
- SET_RESULT( 0 );
+ SET_STATUS_Success( 0 );
}
}
}
-PRE(sys_setuid16, 0)
+PRE(sys_setuid16)
{
PRINT("sys_setuid16 ( %d )", ARG1);
PRE_REG_READ1(long, "setuid16", vki_old_uid_t, uid);
}
-PRE(sys_setuid, 0)
-{
- PRINT("sys_setuid ( %d )", ARG1);
- PRE_REG_READ1(long, "setuid", vki_uid_t, uid);
-}
-
-PRE(sys_socketcall, MayBlock)
-{
-# define ARG2_0 (((UWord*)ARG2)[0])
-# define ARG2_1 (((UWord*)ARG2)[1])
-# define ARG2_2 (((UWord*)ARG2)[2])
-# define ARG2_3 (((UWord*)ARG2)[3])
-# define ARG2_4 (((UWord*)ARG2)[4])
-# define ARG2_5 (((UWord*)ARG2)[5])
-
- PRINT("sys_socketcall ( %d, %p )",ARG1,ARG2);
- PRE_REG_READ2(long, "socketcall", int, call, unsigned long *, args);
-
- switch (ARG1 /* request */) {
-
- case VKI_SYS_SOCKETPAIR:
- /* int socketpair(int d, int type, int protocol, int sv[2]); */
- PRE_MEM_READ( "socketcall.socketpair(args)", ARG2, 4*sizeof(Addr) );
- VG_(generic_PRE_sys_socketpair)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
- break;
-
- case VKI_SYS_SOCKET:
- /* int socket(int domain, int type, int protocol); */
- PRE_MEM_READ( "socketcall.socket(args)", ARG2, 3*sizeof(Addr) );
- break;
-
- case VKI_SYS_BIND:
- /* int bind(int sockfd, struct sockaddr *my_addr,
- int addrlen); */
- PRE_MEM_READ( "socketcall.bind(args)", ARG2, 3*sizeof(Addr) );
- VG_(generic_PRE_sys_bind)( tid, ARG2_0, ARG2_1, ARG2_2 );
- break;
-
- case VKI_SYS_LISTEN:
- /* int listen(int s, int backlog); */
- PRE_MEM_READ( "socketcall.listen(args)", ARG2, 2*sizeof(Addr) );
- break;
-
- case VKI_SYS_ACCEPT: {
- /* int accept(int s, struct sockaddr *addr, int *addrlen); */
- PRE_MEM_READ( "socketcall.accept(args)", ARG2, 3*sizeof(Addr) );
- VG_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
- break;
- }
-
- case VKI_SYS_SENDTO:
- /* int sendto(int s, const void *msg, int len,
- unsigned int flags,
- const struct sockaddr *to, int tolen); */
- PRE_MEM_READ( "socketcall.sendto(args)", ARG2, 6*sizeof(Addr) );
- VG_(generic_PRE_sys_sendto)( tid, ARG2_0, ARG2_1, ARG2_2,
- ARG2_3, ARG2_4, ARG2_5 );
- break;
-
- case VKI_SYS_SEND:
- /* int send(int s, const void *msg, size_t len, int flags); */
- PRE_MEM_READ( "socketcall.send(args)", ARG2, 4*sizeof(Addr) );
- VG_(generic_PRE_sys_send)( tid, ARG2_0, ARG2_1, ARG2_2 );
- break;
-
- case VKI_SYS_RECVFROM:
- /* int recvfrom(int s, void *buf, int len, unsigned int flags,
- struct sockaddr *from, int *fromlen); */
- PRE_MEM_READ( "socketcall.recvfrom(args)", ARG2, 6*sizeof(Addr) );
- VG_(generic_PRE_sys_recvfrom)( tid, ARG2_0, ARG2_1, ARG2_2,
- ARG2_3, ARG2_4, ARG2_5 );
- break;
-
- case VKI_SYS_RECV:
- /* int recv(int s, void *buf, int len, unsigned int flags); */
- /* man 2 recv says:
- The recv call is normally used only on a connected socket
- (see connect(2)) and is identical to recvfrom with a NULL
- from parameter.
- */
- PRE_MEM_READ( "socketcall.recv(args)", ARG2, 4*sizeof(Addr) );
- VG_(generic_PRE_sys_recv)( tid, ARG2_0, ARG2_1, ARG2_2 );
- break;
-
- case VKI_SYS_CONNECT:
- /* int connect(int sockfd,
- struct sockaddr *serv_addr, int addrlen ); */
- PRE_MEM_READ( "socketcall.connect(args)", ARG2, 3*sizeof(Addr) );
- VG_(generic_PRE_sys_connect)( tid, ARG2_0, ARG2_1, ARG2_2 );
- break;
-
- case VKI_SYS_SETSOCKOPT:
- /* int setsockopt(int s, int level, int optname,
- const void *optval, int optlen); */
- PRE_MEM_READ( "socketcall.setsockopt(args)", ARG2, 5*sizeof(Addr) );
- VG_(generic_PRE_sys_setsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
- ARG2_3, ARG2_4 );
- break;
-
- case VKI_SYS_GETSOCKOPT:
- /* int getsockopt(int s, int level, int optname,
- void *optval, socklen_t *optlen); */
- PRE_MEM_READ( "socketcall.getsockopt(args)", ARG2, 5*sizeof(Addr) );
- VG_(generic_PRE_sys_getsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
- ARG2_3, ARG2_4 );
- break;
-
- case VKI_SYS_GETSOCKNAME:
- /* int getsockname(int s, struct sockaddr* name, int* namelen) */
- PRE_MEM_READ( "socketcall.getsockname(args)", ARG2, 3*sizeof(Addr) );
- VG_(generic_PRE_sys_getsockname)( tid, ARG2_0, ARG2_1, ARG2_2 );
- break;
-
- case VKI_SYS_GETPEERNAME:
- /* int getpeername(int s, struct sockaddr* name, int* namelen) */
- PRE_MEM_READ( "socketcall.getpeername(args)", ARG2, 3*sizeof(Addr) );
- VG_(generic_PRE_sys_getpeername)( tid, ARG2_0, ARG2_1, ARG2_2 );
- break;
-
- case VKI_SYS_SHUTDOWN:
- /* int shutdown(int s, int how); */
- PRE_MEM_READ( "socketcall.shutdown(args)", ARG2, 2*sizeof(Addr) );
- break;
-
- case VKI_SYS_SENDMSG: {
- /* int sendmsg(int s, const struct msghdr *msg, int flags); */
-
- /* this causes warnings, and I don't get why. glibc bug?
- * (after all it's glibc providing the arguments array)
- PRE_MEM_READ( "socketcall.sendmsg(args)", ARG2, 3*sizeof(Addr) );
- */
- VG_(generic_PRE_sys_sendmsg)( tid, ARG2_0, ARG2_1 );
- break;
- }
-
- case VKI_SYS_RECVMSG: {
- /* int recvmsg(int s, struct msghdr *msg, int flags); */
-
- /* this causes warnings, and I don't get why. glibc bug?
- * (after all it's glibc providing the arguments array)
- PRE_MEM_READ("socketcall.recvmsg(args)", ARG2, 3*sizeof(Addr) );
- */
- VG_(generic_PRE_sys_recvmsg)( tid, ARG2_0, ARG2_1 );
- break;
- }
-
- default:
- VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%x",ARG1);
- SET_RESULT( -VKI_EINVAL );
- break;
- }
-# undef ARG2_0
-# undef ARG2_1
-# undef ARG2_2
-# undef ARG2_3
-# undef ARG2_4
-# undef ARG2_5
-}
-
-POST(sys_socketcall)
-{
-# define ARG2_0 (((UWord*)ARG2)[0])
-# define ARG2_1 (((UWord*)ARG2)[1])
-# define ARG2_2 (((UWord*)ARG2)[2])
-# define ARG2_3 (((UWord*)ARG2)[3])
-# define ARG2_4 (((UWord*)ARG2)[4])
-# define ARG2_5 (((UWord*)ARG2)[5])
-
- UWord r;
- switch (ARG1 /* request */) {
-
- case VKI_SYS_SOCKETPAIR:
- VG_(generic_POST_sys_socketpair)( tid, RES, ARG2_0,
- ARG2_1, ARG2_2, ARG2_3 );
- break;
-
- case VKI_SYS_SOCKET:
- r = VG_(generic_POST_sys_socket)( tid, RES );
- SET_RESULT(r);
- break;
-
- case VKI_SYS_BIND:
- /* int bind(int sockfd, struct sockaddr *my_addr,
- int addrlen); */
- break;
-
- case VKI_SYS_LISTEN:
- /* int listen(int s, int backlog); */
- break;
-
- case VKI_SYS_ACCEPT:
- /* int accept(int s, struct sockaddr *addr, int *addrlen); */
- r = VG_(generic_POST_sys_accept)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
- SET_RESULT(r);
- break;
-
- case VKI_SYS_SENDTO:
- break;
-
- case VKI_SYS_SEND:
- break;
-
- case VKI_SYS_RECVFROM:
- VG_(generic_POST_sys_recvfrom)( tid, RES, ARG2_0, ARG2_1, ARG2_2,
- ARG2_3, ARG2_4, ARG2_5 );
- break;
-
- case VKI_SYS_RECV:
- VG_(generic_POST_sys_recv)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
- break;
-
- case VKI_SYS_CONNECT:
- break;
-
- case VKI_SYS_SETSOCKOPT:
- break;
-
- case VKI_SYS_GETSOCKOPT:
- VG_(generic_POST_sys_getsockopt)( tid, RES, ARG2_0, ARG2_1,
- ARG2_2, ARG2_3, ARG2_4 );
- break;
-
- case VKI_SYS_GETSOCKNAME:
- VG_(generic_POST_sys_getsockname)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
- break;
-
- case VKI_SYS_GETPEERNAME:
- VG_(generic_POST_sys_getpeername)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
- break;
-
- case VKI_SYS_SHUTDOWN:
- break;
-
- case VKI_SYS_SENDMSG:
- break;
-
- case VKI_SYS_RECVMSG:
- VG_(generic_POST_sys_recvmsg)( tid, RES, ARG2_0, ARG2_1 );
- break;
-
- default:
- VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%x",ARG1);
- VG_(core_panic)("... bye!\n");
- break; /*NOTREACHED*/
- }
-# undef ARG2_0
-# undef ARG2_1
-# undef ARG2_2
-# undef ARG2_3
-# undef ARG2_4
-# undef ARG2_5
-}
-
-PRE(sys_newstat, 0)
-{
- PRINT("sys_newstat ( %p(%s), %p )", ARG1,ARG1,ARG2);
- PRE_REG_READ2(long, "stat", char *, file_name, struct stat *, buf);
- PRE_MEM_RASCIIZ( "stat(file_name)", ARG1 );
- PRE_MEM_WRITE( "stat(buf)", ARG2, sizeof(struct vki_stat) );
-}
-
-POST(sys_newstat)
-{
- POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
-}
-
-PRE(sys_statfs, 0)
-{
- PRINT("sys_statfs ( %p, %p )",ARG1,ARG2);
- PRE_REG_READ2(long, "statfs", const char *, path, struct statfs *, buf);
- PRE_MEM_RASCIIZ( "statfs(path)", ARG1 );
- PRE_MEM_WRITE( "statfs(buf)", ARG2, sizeof(struct vki_statfs) );
-}
-
-POST(sys_statfs)
-{
- POST_MEM_WRITE( ARG2, sizeof(struct vki_statfs) );
-}
-
-PRE(sys_statfs64, 0)
-{
- PRINT("sys_statfs64 ( %p, %llu, %p )",ARG1,(ULong)ARG2,ARG3);
- PRE_REG_READ3(long, "statfs64",
- const char *, path, vki_size_t, size, struct statfs64 *, buf);
- PRE_MEM_RASCIIZ( "statfs64(path)", ARG1 );
- PRE_MEM_WRITE( "statfs64(buf)", ARG3, ARG2 );
-}
-
-POST(sys_statfs64)
-{
- POST_MEM_WRITE( ARG3, ARG2 );
-}
-
-PRE(sys_symlink, MayBlock)
-{
- PRINT("sys_symlink ( %p, %p )",ARG1,ARG2);
- PRE_REG_READ2(long, "symlink", const char *, oldpath, const char *, newpath);
- PRE_MEM_RASCIIZ( "symlink(oldpath)", ARG1 );
- PRE_MEM_RASCIIZ( "symlink(newpath)", ARG2 );
-}
-
-// See comment above PRE(sys_lstat64) for an explanation of this #ifdef.
-#ifndef __amd64__
-PRE(sys_stat64, 0)
-{
- PRINT("sys_stat64 ( %p, %p )",ARG1,ARG2);
- PRE_REG_READ2(long, "stat64", char *, file_name, struct stat64 *, buf);
- PRE_MEM_RASCIIZ( "stat64(file_name)", ARG1 );
- PRE_MEM_WRITE( "stat64(buf)", ARG2, sizeof(struct vki_stat64) );
-}
-
-POST(sys_stat64)
-{
- POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
-}
-
-PRE(sys_fstat64, 0)
-{
- PRINT("sys_fstat64 ( %d, %p )",ARG1,ARG2);
- PRE_REG_READ2(long, "fstat64", unsigned long, fd, struct stat64 *, buf);
- PRE_MEM_WRITE( "fstat64(buf)", ARG2, sizeof(struct vki_stat64) );
-}
-
-POST(sys_fstat64)
-{
- POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
-}
-#endif
-
-PRE(sys_time, 0)
+//zz PRE(sys_setuid, 0)
+//zz {
+//zz PRINT("sys_setuid ( %d )", ARG1);
+//zz PRE_REG_READ1(long, "setuid", vki_uid_t, uid);
+//zz }
+
+//zz PRE(sys_newstat, 0)
+//zz {
+//zz PRINT("sys_newstat ( %p(%s), %p )", ARG1,ARG1,ARG2);
+//zz PRE_REG_READ2(long, "stat", char *, file_name, struct stat *, buf);
+//zz PRE_MEM_RASCIIZ( "stat(file_name)", ARG1 );
+//zz PRE_MEM_WRITE( "stat(buf)", ARG2, sizeof(struct vki_stat) );
+//zz }
+//zz
+//zz POST(sys_newstat)
+//zz {
+//zz POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
+//zz }
+//zz
+//zz PRE(sys_statfs, 0)
+//zz {
+//zz PRINT("sys_statfs ( %p, %p )",ARG1,ARG2);
+//zz PRE_REG_READ2(long, "statfs", const char *, path, struct statfs *, buf);
+//zz PRE_MEM_RASCIIZ( "statfs(path)", ARG1 );
+//zz PRE_MEM_WRITE( "statfs(buf)", ARG2, sizeof(struct vki_statfs) );
+//zz }
+//zz
+//zz POST(sys_statfs)
+//zz {
+//zz POST_MEM_WRITE( ARG2, sizeof(struct vki_statfs) );
+//zz }
+//zz
+//zz PRE(sys_statfs64, 0)
+//zz {
+//zz PRINT("sys_statfs64 ( %p, %llu, %p )",ARG1,(ULong)ARG2,ARG3);
+//zz PRE_REG_READ3(long, "statfs64",
+//zz const char *, path, vki_size_t, size, struct statfs64 *, buf);
+//zz PRE_MEM_RASCIIZ( "statfs64(path)", ARG1 );
+//zz PRE_MEM_WRITE( "statfs64(buf)", ARG3, ARG2 );
+//zz }
+//zz
+//zz POST(sys_statfs64)
+//zz {
+//zz POST_MEM_WRITE( ARG3, ARG2 );
+//zz }
+//zz
+//zz PRE(sys_symlink, SfMayBlock)
+//zz {
+//zz PRINT("sys_symlink ( %p, %p )",ARG1,ARG2);
+//zz PRE_REG_READ2(long, "symlink", const char *, oldpath, const char *, newpath);
+//zz PRE_MEM_RASCIIZ( "symlink(oldpath)", ARG1 );
+//zz PRE_MEM_RASCIIZ( "symlink(newpath)", ARG2 );
+//zz }
+
+PRE(sys_time)
{
/* time_t time(time_t *t); */
PRINT("sys_time ( %p )",ARG1);
@@ -5382,34 +4967,35 @@ POST(sys_time)
}
}
-PRE(sys_times, 0)
-{
- PRINT("sys_times ( %p )", ARG1);
- PRE_REG_READ1(long, "times", struct tms *, buf);
- PRE_MEM_WRITE( "times(buf)", ARG1, sizeof(struct vki_tms) );
-}
-
-POST(sys_times)
-{
- if (ARG1 != 0) {
- POST_MEM_WRITE( ARG1, sizeof(struct vki_tms) );
- }
-}
-
-PRE(sys_umask, 0)
-{
- PRINT("sys_umask ( %d )", ARG1);
- PRE_REG_READ1(long, "umask", int, mask);
-}
-
-PRE(sys_unlink, MayBlock)
-{
+//zz PRE(sys_times, 0)
+//zz {
+//zz PRINT("sys_times ( %p )", ARG1);
+//zz PRE_REG_READ1(long, "times", struct tms *, buf);
+//zz PRE_MEM_WRITE( "times(buf)", ARG1, sizeof(struct vki_tms) );
+//zz }
+//zz
+//zz POST(sys_times)
+//zz {
+//zz if (ARG1 != 0) {
+//zz POST_MEM_WRITE( ARG1, sizeof(struct vki_tms) );
+//zz }
+//zz }
+//zz
+//zz PRE(sys_umask, 0)
+//zz {
+//zz PRINT("sys_umask ( %d )", ARG1);
+//zz PRE_REG_READ1(long, "umask", int, mask);
+//zz }
+
+PRE(sys_unlink)
+{
+ *flags |= SfMayBlock;
PRINT("sys_unlink ( %p(%s) )", ARG1,ARG1);
PRE_REG_READ1(long, "unlink", const char *, pathname);
PRE_MEM_RASCIIZ( "unlink(pathname)", ARG1 );
}
-PRE(sys_newuname, 0)
+PRE(sys_newuname)
{
PRINT("sys_newuname ( %p )", ARG1);
PRE_REG_READ1(long, "uname", struct new_utsname *, buf);
@@ -5423,17 +5009,18 @@ POST(sys_newuname)
}
}
-PRE(sys_utime, MayBlock)
-{
- PRINT("sys_utime ( %p, %p )", ARG1,ARG2);
- PRE_REG_READ2(long, "utime", char *, filename, struct utimbuf *, buf);
- PRE_MEM_RASCIIZ( "utime(filename)", ARG1 );
- if (ARG2 != 0)
- PRE_MEM_READ( "utime(buf)", ARG2, sizeof(struct vki_utimbuf) );
-}
+//zz PRE(sys_utime, SfMayBlock)
+//zz {
+//zz PRINT("sys_utime ( %p, %p )", ARG1,ARG2);
+//zz PRE_REG_READ2(long, "utime", char *, filename, struct utimbuf *, buf);
+//zz PRE_MEM_RASCIIZ( "utime(filename)", ARG1 );
+//zz if (ARG2 != 0)
+//zz PRE_MEM_READ( "utime(buf)", ARG2, sizeof(struct vki_utimbuf) );
+//zz }
-PRE(sys_waitpid, MayBlock)
+PRE(sys_waitpid)
{
+ *flags |= SfMayBlock;
PRINT("sys_waitpid ( %d, %p, %d )", ARG1,ARG2,ARG3);
PRE_REG_READ3(long, "waitpid",
vki_pid_t, pid, unsigned int *, status, int, options);
@@ -5448,8 +5035,9 @@ POST(sys_waitpid)
POST_MEM_WRITE( ARG2, sizeof(int) );
}
-PRE(sys_wait4, MayBlock)
+PRE(sys_wait4)
{
+ *flags |= SfMayBlock;
PRINT("sys_wait4 ( %d, %p, %d, %p )", ARG1,ARG2,ARG3,ARG4);
PRE_REG_READ4(long, "wait4",
@@ -5469,16 +5057,17 @@ POST(sys_wait4)
POST_MEM_WRITE( ARG4, sizeof(struct vki_rusage) );
}
-PRE(sys_writev, MayBlock)
+PRE(sys_writev)
{
Int i;
struct vki_iovec * vec;
+ *flags |= SfMayBlock;
PRINT("sys_writev ( %d, %p, %llu )",ARG1,ARG2,(ULong)ARG3);
PRE_REG_READ3(ssize_t, "writev",
unsigned long, fd, const struct iovec *, vector,
unsigned long, count);
if (!VG_(fd_allowed)(ARG1, "writev", tid, False)) {
- SET_RESULT( -VKI_EBADF );
+ SET_STATUS_Failure( VKI_EBADF );
} else {
PRE_MEM_READ( "writev(vector)",
ARG2, ARG3 * sizeof(struct vki_iovec) );
@@ -5492,69 +5081,70 @@ PRE(sys_writev, MayBlock)
}
}
-PRE(sys_utimes, 0)
-{
- PRINT("sys_utimes ( %p, %p )", ARG1,ARG2);
- PRE_REG_READ2(long, "utimes", char *, filename, struct timeval *, tvp);
- PRE_MEM_RASCIIZ( "utimes(filename)", ARG1 );
- if (ARG2 != 0)
- PRE_MEM_READ( "utimes(tvp)", ARG2, sizeof(struct vki_timeval) );
-}
-
-PRE(sys_sched_setaffinity, 0)
-{
- PRINT("sched_setaffinity ( %d, %d, %p )", ARG1, ARG2, ARG3);
- PRE_REG_READ3(long, "sched_setaffinity",
- vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
- PRE_MEM_READ( "sched_setaffinity(mask)", ARG3, ARG2);
-}
-
-PRE(sys_sched_getaffinity, 0)
-{
- PRINT("sched_getaffinity ( %d, %d, %p )", ARG1, ARG2, ARG3);
- PRE_REG_READ3(long, "sched_getaffinity",
- vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
- PRE_MEM_WRITE( "sched_getaffinity(mask)", ARG3, ARG2);
-}
-
-POST(sys_sched_getaffinity)
-{
- POST_MEM_WRITE(ARG3, ARG2);
-}
-
-PRE(sys_acct, 0)
-{
- PRINT("sys_acct ( %p )", ARG1);
- PRE_REG_READ1(long, "acct", const char *, filename);
- PRE_MEM_RASCIIZ( "acct(filename)", ARG1 );
-}
-
-PRE(sys_pause, MayBlock)
-{
+//zz PRE(sys_utimes, 0)
+//zz {
+//zz PRINT("sys_utimes ( %p, %p )", ARG1,ARG2);
+//zz PRE_REG_READ2(long, "utimes", char *, filename, struct timeval *, tvp);
+//zz PRE_MEM_RASCIIZ( "utimes(filename)", ARG1 );
+//zz if (ARG2 != 0)
+//zz PRE_MEM_READ( "utimes(tvp)", ARG2, sizeof(struct vki_timeval) );
+//zz }
+//zz
+//zz PRE(sys_sched_setaffinity, 0)
+//zz {
+//zz PRINT("sched_setaffinity ( %d, %d, %p )", ARG1, ARG2, ARG3);
+//zz PRE_REG_READ3(long, "sched_setaffinity",
+//zz vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
+//zz PRE_MEM_READ( "sched_setaffinity(mask)", ARG3, ARG2);
+//zz }
+//zz
+//zz PRE(sys_sched_getaffinity, 0)
+//zz {
+//zz PRINT("sched_getaffinity ( %d, %d, %p )", ARG1, ARG2, ARG3);
+//zz PRE_REG_READ3(long, "sched_getaffinity",
+//zz vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
+//zz PRE_MEM_WRITE( "sched_getaffinity(mask)", ARG3, ARG2);
+//zz }
+//zz
+//zz POST(sys_sched_getaffinity)
+//zz {
+//zz POST_MEM_WRITE(ARG3, ARG2);
+//zz }
+//zz
+//zz PRE(sys_acct, 0)
+//zz {
+//zz PRINT("sys_acct ( %p )", ARG1);
+//zz PRE_REG_READ1(long, "acct", const char *, filename);
+//zz PRE_MEM_RASCIIZ( "acct(filename)", ARG1 );
+//zz }
+
+PRE(sys_pause)
+{
+ *flags |= SfMayBlock;
PRINT("sys_pause ( )");
PRE_REG_READ0(long, "pause");
}
-// XXX: x86-specific
-PRE(sys_sigsuspend, MayBlock)
-{
- /* The C library interface to sigsuspend just takes a pointer to
- a signal mask but this system call has three arguments - the first
- two don't appear to be used by the kernel and are always passed as
- zero by glibc and the third is the first word of the signal mask
- so only 32 signals are supported.
-
- In fact glibc normally uses rt_sigsuspend if it is available as
- that takes a pointer to the signal mask so supports more signals.
- */
- PRINT("sys_sigsuspend ( %d, %d, %d )", ARG1,ARG2,ARG3 );
- PRE_REG_READ3(int, "sigsuspend",
- int, history0, int, history1,
- vki_old_sigset_t, mask);
-}
+//zz // XXX: x86-specific
+//zz PRE(sys_sigsuspend, SfMayBlock)
+//zz {
+//zz /* The C library interface to sigsuspend just takes a pointer to
+//zz a signal mask but this system call has three arguments - the first
+//zz two don't appear to be used by the kernel and are always passed as
+//zz zero by glibc and the third is the first word of the signal mask
+//zz so only 32 signals are supported.
+//zz
+//zz In fact glibc normally uses rt_sigsuspend if it is available as
+//zz that takes a pointer to the signal mask so supports more signals.
+//zz */
+//zz PRINT("sys_sigsuspend ( %d, %d, %d )", ARG1,ARG2,ARG3 );
+//zz PRE_REG_READ3(int, "sigsuspend",
+//zz int, history0, int, history1,
+//zz vki_old_sigset_t, mask);
+//zz }
// XXX: x86-specific
-PRE(sys_rt_sigsuspend, MayBlock)
+PRE(sys_rt_sigsuspend)
{
/* The C library interface to sigsuspend just takes a pointer to
a signal mask but this system call has two arguments - a pointer
@@ -5562,6 +5152,7 @@ PRE(sys_rt_sigsuspend, MayBlock)
on the size being equal to sizeof(sigset_t) however and will just
return EINVAL if it isn't.
*/
+ *flags |= SfMayBlock;
PRINT("sys_rt_sigsuspend ( %p, %d )", ARG1,ARG2 );
PRE_REG_READ2(int, "rt_sigsuspend", vki_sigset_t *, mask, vki_size_t, size)
if (ARG1 != (Addr)NULL) {
@@ -5569,8 +5160,9 @@ PRE(sys_rt_sigsuspend, MayBlock)
}
}
-PRE(sys_rt_sigtimedwait, MayBlock)
+PRE(sys_rt_sigtimedwait)
{
+ *flags |= SfMayBlock;
PRINT("sys_rt_sigtimedwait ( %p, %p, %p, %lld )",
ARG1,ARG2,ARG3,(ULong)ARG4);
PRE_REG_READ4(long, "rt_sigtimedwait",
@@ -5590,28 +5182,28 @@ POST(sys_rt_sigtimedwait)
POST_MEM_WRITE( ARG2, sizeof(vki_siginfo_t) );
}
-PRE(sys_rt_sigqueueinfo, 0)
-{
- PRINT("sys_rt_sigqueueinfo(%d, %d, %p)", ARG1, ARG2, ARG3);
- PRE_REG_READ3(long, "rt_sigqueueinfo",
- int, pid, int, sig, vki_siginfo_t *, uinfo);
- if (ARG2 != 0)
- PRE_MEM_READ( "rt_sigqueueinfo(uinfo)", ARG3, sizeof(vki_siginfo_t) );
-}
-
-POST(sys_rt_sigqueueinfo)
-{
- PRINT("sys_rt_sigqueueinfo(%d, %d, %p)", ARG1, ARG2, ARG3);
- PRE_REG_READ3(long, "rt_sigqueueinfo",
- int, pid, int, sig, vki_siginfo_t *, uinfo);
- if (ARG2 != 0)
- PRE_MEM_READ( "rt_sigqueueinfo(uinfo)", ARG3, sizeof(vki_siginfo_t) );
- if (!VG_(client_signal_OK)(ARG2))
- SET_RESULT( -VKI_EINVAL );
-}
+//zz PRE(sys_rt_sigqueueinfo, 0)
+//zz {
+//zz PRINT("sys_rt_sigqueueinfo(%d, %d, %p)", ARG1, ARG2, ARG3);
+//zz PRE_REG_READ3(long, "rt_sigqueueinfo",
+//zz int, pid, int, sig, vki_siginfo_t *, uinfo);
+//zz if (ARG2 != 0)
+//zz PRE_MEM_READ( "rt_sigqueueinfo(uinfo)", ARG3, sizeof(vki_siginfo_t) );
+//zz }
+//zz
+//zz POST(sys_rt_sigqueueinfo)
+//zz {
+//zz PRINT("sys_rt_sigqueueinfo(%d, %d, %p)", ARG1, ARG2, ARG3);
+//zz PRE_REG_READ3(long, "rt_sigqueueinfo",
+//zz int, pid, int, sig, vki_siginfo_t *, uinfo);
+//zz if (ARG2 != 0)
+//zz PRE_MEM_READ( "rt_sigqueueinfo(uinfo)", ARG3, sizeof(vki_siginfo_t) );
+//zz if (!VG_(client_signal_OK)(ARG2))
+//zz SET_STATUS_( -VKI_EINVAL );
+//zz }
// XXX: x86-specific
-PRE(sys_sigaltstack, Special)
+PRE(sys_sigaltstack)
{
/* int sigaltstack(const stack_t *ss, stack_t *oss); */
PRINT("sigaltstack ( %p, %p )",ARG1,ARG2);
@@ -5624,18 +5216,21 @@ PRE(sys_sigaltstack, Special)
PRE_MEM_WRITE( "sigaltstack(oss)", ARG2, sizeof(vki_stack_t) );
}
- SET_RESULT( VG_(do_sys_sigaltstack) (tid, (vki_stack_t*)ARG1,
- (vki_stack_t*)ARG2) );
+ SET_STATUS_from_SysRes(
+ VG_(do_sys_sigaltstack) (tid, (vki_stack_t*)ARG1,
+ (vki_stack_t*)ARG2)
+ );
}
POST(sys_sigaltstack)
{
+ vg_assert(SUCCESS);
if (RES == 0 && ARG2 != 0)
POST_MEM_WRITE( ARG2, sizeof(vki_stack_t));
}
// XXX: x86-specific
-PRE(sys_rt_sigaction, Special)
+PRE(sys_rt_sigaction)
{
PRINT("sys_rt_sigaction ( %d, %p, %p, %d )", ARG1,ARG2,ARG3,ARG4);
PRE_REG_READ4(long, "rt_sigaction",
@@ -5651,7 +5246,7 @@ PRE(sys_rt_sigaction, Special)
// sys_rt_sigaction... perhaps this function should be renamed
// VG_(do_sys_rt_sigaction)() --njn
- SET_RESULT(
+ SET_STATUS_from_SysRes(
VG_(do_sys_sigaction)(ARG1, (const struct vki_sigaction *)ARG2,
(struct vki_sigaction *)ARG3)
);
@@ -5659,6 +5254,7 @@ PRE(sys_rt_sigaction, Special)
POST(sys_rt_sigaction)
{
+ vg_assert(SUCCESS);
if (RES == 0 && ARG3 != 0)
POST_MEM_WRITE( ARG3, sizeof(struct vki_sigaction));
}
@@ -5666,8 +5262,8 @@ POST(sys_rt_sigaction)
// XXX: This syscall is not used on amd64 -- it only provides
// sys_rt_sigprocmask, which uses sigset_t rather than old_sigset_t.
// This wrapper is only suitable for 32-bit architectures.
-#ifndef __amd64__
-PRE(sys_sigprocmask, Special)
+#if defined(VGP_x86_linux)
+PRE(sys_sigprocmask)
{
vki_old_sigset_t* set;
vki_old_sigset_t* oldset;
@@ -5692,7 +5288,7 @@ PRE(sys_sigprocmask, Special)
if (set)
bigger_set.sig[0] = *(vki_old_sigset_t*)set;
- SET_RESULT(
+ SET_STATUS_from_SysRes(
VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
set ? &bigger_set : NULL,
oldset ? &bigger_oldset : NULL)
@@ -5700,16 +5296,20 @@ PRE(sys_sigprocmask, Special)
if (oldset)
*oldset = bigger_oldset.sig[0];
+
+ if (SUCCESS)
+ *flags |= SfPollAfter;
}
POST(sys_sigprocmask)
{
+ vg_assert(SUCCESS);
if (RES == 0 && ARG3 != 0)
POST_MEM_WRITE( ARG3, sizeof(vki_old_sigset_t));
}
#endif
-PRE(sys_rt_sigprocmask, Special)
+PRE(sys_rt_sigprocmask)
{
PRINT("sys_rt_sigprocmask ( %d, %p, %p, %llu )",ARG1,ARG2,ARG3,(ULong)ARG4);
PRE_REG_READ4(long, "rt_sigprocmask",
@@ -5722,235 +5322,240 @@ PRE(sys_rt_sigprocmask, Special)
// Like the kernel, we fail if the sigsetsize is not exactly what we expect.
if (sizeof(vki_sigset_t) != ARG4)
- SET_RESULT( -VKI_EMFILE );
+ SET_STATUS_Failure( VKI_EMFILE );
else {
- SET_RESULT( VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
+ SET_STATUS_from_SysRes(
+ VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
(vki_sigset_t*) ARG2,
(vki_sigset_t*) ARG3 )
);
}
+
+ if (SUCCESS)
+ *flags |= SfPollAfter;
}
POST(sys_rt_sigprocmask)
{
+ vg_assert(SUCCESS);
if (RES == 0 && ARG3 != 0)
POST_MEM_WRITE( ARG3, sizeof(vki_sigset_t));
}
-PRE(sys_sigpending, 0)
-{
- PRINT( "sys_sigpending ( %p )", ARG1 );
- PRE_REG_READ1(long, "sigpending", vki_old_sigset_t *, set);
- PRE_MEM_WRITE( "sigpending(set)", ARG1, sizeof(vki_old_sigset_t));
-}
-
-POST(sys_sigpending)
-{
- POST_MEM_WRITE( ARG1, sizeof(vki_old_sigset_t) ) ;
-}
-
-PRE(sys_rt_sigpending, 0)
-{
- PRINT( "sys_rt_sigpending ( %p )", ARG1 );
- PRE_REG_READ2(long, "rt_sigpending",
- vki_sigset_t *, set, vki_size_t, sigsetsize);
- PRE_MEM_WRITE( "rt_sigpending(set)", ARG1, sizeof(vki_sigset_t));
-}
-
-POST(sys_rt_sigpending)
-{
- POST_MEM_WRITE( ARG1, sizeof(vki_sigset_t) ) ;
-}
-
-PRE(sys_mq_open, 0)
-{
- PRINT("sys_mq_open( %p(%s), %d, %lld, %p )",
- ARG1,ARG1,ARG2,(ULong)ARG3,ARG4);
- PRE_REG_READ4(long, "mq_open",
- const char *, name, int, oflag, vki_mode_t, mode,
- struct mq_attr *, attr);
- PRE_MEM_RASCIIZ( "mq_open(name)", ARG1 );
- if ((ARG2 & VKI_O_CREAT) != 0 && ARG4 != 0) {
- const struct vki_mq_attr *attr = (struct vki_mq_attr *)ARG4;
- PRE_MEM_READ( "mq_open(attr->mq_maxmsg)",
- (Addr)&attr->mq_maxmsg, sizeof(attr->mq_maxmsg) );
- PRE_MEM_READ( "mq_open(attr->mq_msgsize)",
- (Addr)&attr->mq_msgsize, sizeof(attr->mq_msgsize) );
- }
-}
-
-POST(sys_mq_open)
-{
- if (!VG_(fd_allowed)(RES, "mq_open", tid, True)) {
- VG_(close)(RES);
- SET_RESULT( -VKI_EMFILE );
- } else {
- if (VG_(clo_track_fds))
- VG_(record_fd_open)(tid, RES, VG_(arena_strdup)(VG_AR_CORE, (Char*)ARG1));
- }
-}
-
-PRE(sys_mq_unlink, 0)
-{
- PRINT("sys_mq_unlink ( %p(%s) )", ARG1,ARG1);
- PRE_REG_READ1(long, "mq_unlink", const char *, name);
- PRE_MEM_RASCIIZ( "mq_unlink(name)", ARG1 );
-}
-
-PRE(sys_mq_timedsend, MayBlock)
-{
- PRINT("sys_mq_timedsend ( %d, %p, %llu, %d, %p )",
- ARG1,ARG2,(ULong)ARG3,ARG4,ARG5);
- PRE_REG_READ5(long, "mq_timedsend",
- vki_mqd_t, mqdes, const char *, msg_ptr, vki_size_t, msg_len,
- unsigned int, msg_prio, const struct timespec *, abs_timeout);
- if (!VG_(fd_allowed)(ARG1, "mq_timedsend", tid, False)) {
- SET_RESULT( -VKI_EBADF );
- } else {
- PRE_MEM_READ( "mq_timedsend(msg_ptr)", ARG2, ARG3 );
- if (ARG5 != 0)
- PRE_MEM_READ( "mq_timedsend(abs_timeout)", ARG5,
- sizeof(struct vki_timespec) );
- }
-}
-
-PRE(sys_mq_timedreceive, MayBlock)
-{
- PRINT("sys_mq_timedreceive( %d, %p, %llu, %p, %p )",
- ARG1,ARG2,(ULong)ARG3,ARG4,ARG5);
- PRE_REG_READ5(ssize_t, "mq_timedreceive",
- vki_mqd_t, mqdes, char *, msg_ptr, vki_size_t, msg_len,
- unsigned int *, msg_prio,
- const struct timespec *, abs_timeout);
- if (!VG_(fd_allowed)(ARG1, "mq_timedreceive", tid, False)) {
- SET_RESULT( -VKI_EBADF );
- } else {
- PRE_MEM_WRITE( "mq_timedreceive(msg_ptr)", ARG2, ARG3 );
- if (ARG4 != 0)
- PRE_MEM_WRITE( "mq_timedreceive(msg_prio)",
- ARG4, sizeof(unsigned int) );
- if (ARG5 != 0)
- PRE_MEM_READ( "mq_timedreceive(abs_timeout)",
- ARG5, sizeof(struct vki_timespec) );
- }
-}
-
-POST(sys_mq_timedreceive)
-{
- POST_MEM_WRITE( ARG2, ARG3 );
- if (ARG4 != 0)
- POST_MEM_WRITE( ARG4, sizeof(unsigned int) );
-}
-
-PRE(sys_mq_notify, 0)
-{
- PRINT("sys_mq_notify( %d, %p )", ARG1,ARG2 );
- PRE_REG_READ2(long, "mq_notify",
- vki_mqd_t, mqdes, const struct sigevent *, notification);
- if (!VG_(fd_allowed)(ARG1, "mq_notify", tid, False))
- SET_RESULT( -VKI_EBADF );
- else if (ARG2 != 0)
- PRE_MEM_READ( "mq_notify(notification)",
- ARG2, sizeof(struct vki_sigevent) );
-}
-
-PRE(sys_mq_getsetattr, 0)
-{
- PRINT("sys_mq_getsetattr( %d, %p, %p )", ARG1,ARG2,ARG3 );
- PRE_REG_READ3(long, "mq_getsetattr",
- vki_mqd_t, mqdes, const struct mq_attr *, mqstat,
- struct mq_attr *, omqstat);
- if (!VG_(fd_allowed)(ARG1, "mq_getsetattr", tid, False)) {
- SET_RESULT( -VKI_EBADF );
- } else {
- if (ARG2 != 0) {
- const struct vki_mq_attr *attr = (struct vki_mq_attr *)ARG2;
- PRE_MEM_READ( "mq_getsetattr(mqstat->mq_flags)",
- (Addr)&attr->mq_flags, sizeof(attr->mq_flags) );
- }
- if (ARG3 != 0)
- PRE_MEM_WRITE( "mq_getsetattr(omqstat)", ARG3,
- sizeof(struct vki_mq_attr) );
- }
-}
-
-POST(sys_mq_getsetattr)
-{
- if (ARG3 != 0)
- POST_MEM_WRITE( ARG3, sizeof(struct vki_mq_attr) );
-}
-
-PRE(sys_timer_create, 0)
-{
- PRINT("sys_timer_create( %d, %p, %p )", ARG1,ARG2,ARG3);
- PRE_REG_READ3(long, "timer_create",
- vki_clockid_t, clockid, struct sigevent *, evp,
- vki_timer_t *, timerid);
- if (ARG2 != 0)
- PRE_MEM_READ( "timer_create(evp)", ARG2, sizeof(struct vki_sigevent) );
- PRE_MEM_WRITE( "timer_create(timerid)", ARG3, sizeof(vki_timer_t) );
-}
-
-POST(sys_timer_create)
-{
- POST_MEM_WRITE( ARG3, sizeof(vki_timer_t) );
-}
-
-PRE(sys_timer_settime, 0)
-{
- PRINT("sys_timer_settime( %lld, %d, %p, %p )", (ULong)ARG1,ARG2,ARG3,ARG4);
- PRE_REG_READ4(long, "timer_settime",
- vki_timer_t, timerid, int, flags,
- const struct itimerspec *, value,
- struct itimerspec *, ovalue);
- PRE_MEM_READ( "timer_settime(value)", ARG3,
- sizeof(struct vki_itimerspec) );
- if (ARG4 != 0)
- PRE_MEM_WRITE( "timer_settime(ovalue)", ARG4,
- sizeof(struct vki_itimerspec) );
-}
-
-POST(sys_timer_settime)
-{
- if (ARG4 != 0)
- POST_MEM_WRITE( ARG4, sizeof(struct vki_itimerspec) );
-}
-
-PRE(sys_timer_gettime, 0)
-{
- PRINT("sys_timer_gettime( %lld, %p )", (ULong)ARG1,ARG2);
- PRE_REG_READ2(long, "timer_gettime",
- vki_timer_t, timerid, struct itimerspec *, value);
- PRE_MEM_WRITE( "timer_gettime(value)", ARG2,
- sizeof(struct vki_itimerspec));
-}
-
-POST(sys_timer_gettime)
-{
- POST_MEM_WRITE( ARG2, sizeof(struct vki_itimerspec) );
-}
-
-PRE(sys_timer_getoverrun, 0)
-{
- PRINT("sys_timer_getoverrun( %p )", ARG1);
- PRE_REG_READ1(long, "timer_getoverrun", vki_timer_t, timerid);
-}
-
-PRE(sys_timer_delete, 0)
-{
- PRINT("sys_timer_delete( %p )", ARG1);
- PRE_REG_READ1(long, "timer_delete", vki_timer_t, timerid);
-}
-
-PRE(sys_clock_settime, 0)
-{
- PRINT("sys_clock_settime( %d, %p )", ARG1,ARG2);
- PRE_REG_READ2(long, "clock_settime",
- vki_clockid_t, clk_id, const struct timespec *, tp);
- PRE_MEM_READ( "clock_settime(tp)", ARG2, sizeof(struct vki_timespec) );
-}
-
-PRE(sys_clock_gettime, 0)
+//zz PRE(sys_sigpending, 0)
+//zz {
+//zz PRINT( "sys_sigpending ( %p )", ARG1 );
+//zz PRE_REG_READ1(long, "sigpending", vki_old_sigset_t *, set);
+//zz PRE_MEM_WRITE( "sigpending(set)", ARG1, sizeof(vki_old_sigset_t));
+//zz }
+//zz
+//zz POST(sys_sigpending)
+//zz {
+//zz POST_MEM_WRITE( ARG1, sizeof(vki_old_sigset_t) ) ;
+//zz }
+//zz
+//zz PRE(sys_rt_sigpending, 0)
+//zz {
+//zz PRINT( "sys_rt_sigpending ( %p )", ARG1 );
+//zz PRE_REG_READ2(long, "rt_sigpending",
+//zz vki_sigset_t *, set, vki_size_t, sigsetsize);
+//zz PRE_MEM_WRITE( "rt_sigpending(set)", ARG1, sizeof(vki_sigset_t));
+//zz }
+//zz
+//zz POST(sys_rt_sigpending)
+//zz {
+//zz POST_MEM_WRITE( ARG1, sizeof(vki_sigset_t) ) ;
+//zz }
+//zz
+//zz PRE(sys_mq_open, 0)
+//zz {
+//zz PRINT("sys_mq_open( %p(%s), %d, %lld, %p )",
+//zz ARG1,ARG1,ARG2,(ULong)ARG3,ARG4);
+//zz PRE_REG_READ4(long, "mq_open",
+//zz const char *, name, int, oflag, vki_mode_t, mode,
+//zz struct mq_attr *, attr);
+//zz PRE_MEM_RASCIIZ( "mq_open(name)", ARG1 );
+//zz if ((ARG2 & VKI_O_CREAT) != 0 && ARG4 != 0) {
+//zz const struct vki_mq_attr *attr = (struct vki_mq_attr *)ARG4;
+//zz PRE_MEM_READ( "mq_open(attr->mq_maxmsg)",
+//zz (Addr)&attr->mq_maxmsg, sizeof(attr->mq_maxmsg) );
+//zz PRE_MEM_READ( "mq_open(attr->mq_msgsize)",
+//zz (Addr)&attr->mq_msgsize, sizeof(attr->mq_msgsize) );
+//zz }
+//zz }
+//zz
+//zz POST(sys_mq_open)
+//zz {
+//zz if (!VG_(fd_allowed)(RES, "mq_open", tid, True)) {
+//zz VG_(close)(RES);
+//zz SET_STATUS_( -VKI_EMFILE );
+//zz } else {
+//zz if (VG_(clo_track_fds))
+//zz VG_(record_fd_open)(tid, RES, VG_(arena_strdup)(VG_AR_CORE, (Char*)ARG1));
+//zz }
+//zz }
+//zz
+//zz PRE(sys_mq_unlink, 0)
+//zz {
+//zz PRINT("sys_mq_unlink ( %p(%s) )", ARG1,ARG1);
+//zz PRE_REG_READ1(long, "mq_unlink", const char *, name);
+//zz PRE_MEM_RASCIIZ( "mq_unlink(name)", ARG1 );
+//zz }
+//zz
+//zz PRE(sys_mq_timedsend, SfMayBlock)
+//zz {
+//zz PRINT("sys_mq_timedsend ( %d, %p, %llu, %d, %p )",
+//zz ARG1,ARG2,(ULong)ARG3,ARG4,ARG5);
+//zz PRE_REG_READ5(long, "mq_timedsend",
+//zz vki_mqd_t, mqdes, const char *, msg_ptr, vki_size_t, msg_len,
+//zz unsigned int, msg_prio, const struct timespec *, abs_timeout);
+//zz if (!VG_(fd_allowed)(ARG1, "mq_timedsend", tid, False)) {
+//zz SET_STATUS_( -VKI_EBADF );
+//zz } else {
+//zz PRE_MEM_READ( "mq_timedsend(msg_ptr)", ARG2, ARG3 );
+//zz if (ARG5 != 0)
+//zz PRE_MEM_READ( "mq_timedsend(abs_timeout)", ARG5,
+//zz sizeof(struct vki_timespec) );
+//zz }
+//zz }
+//zz
+//zz PRE(sys_mq_timedreceive, SfMayBlock)
+//zz {
+//zz PRINT("sys_mq_timedreceive( %d, %p, %llu, %p, %p )",
+//zz ARG1,ARG2,(ULong)ARG3,ARG4,ARG5);
+//zz PRE_REG_READ5(ssize_t, "mq_timedreceive",
+//zz vki_mqd_t, mqdes, char *, msg_ptr, vki_size_t, msg_len,
+//zz unsigned int *, msg_prio,
+//zz const struct timespec *, abs_timeout);
+//zz if (!VG_(fd_allowed)(ARG1, "mq_timedreceive", tid, False)) {
+//zz SET_STATUS_( -VKI_EBADF );
+//zz } else {
+//zz PRE_MEM_WRITE( "mq_timedreceive(msg_ptr)", ARG2, ARG3 );
+//zz if (ARG4 != 0)
+//zz PRE_MEM_WRITE( "mq_timedreceive(msg_prio)",
+//zz ARG4, sizeof(unsigned int) );
+//zz if (ARG5 != 0)
+//zz PRE_MEM_READ( "mq_timedreceive(abs_timeout)",
+//zz ARG5, sizeof(struct vki_timespec) );
+//zz }
+//zz }
+//zz
+//zz POST(sys_mq_timedreceive)
+//zz {
+//zz POST_MEM_WRITE( ARG2, ARG3 );
+//zz if (ARG4 != 0)
+//zz POST_MEM_WRITE( ARG4, sizeof(unsigned int) );
+//zz }
+//zz
+//zz PRE(sys_mq_notify, 0)
+//zz {
+//zz PRINT("sys_mq_notify( %d, %p )", ARG1,ARG2 );
+//zz PRE_REG_READ2(long, "mq_notify",
+//zz vki_mqd_t, mqdes, const struct sigevent *, notification);
+//zz if (!VG_(fd_allowed)(ARG1, "mq_notify", tid, False))
+//zz SET_STATUS_( -VKI_EBADF );
+//zz else if (ARG2 != 0)
+//zz PRE_MEM_READ( "mq_notify(notification)",
+//zz ARG2, sizeof(struct vki_sigevent) );
+//zz }
+//zz
+//zz PRE(sys_mq_getsetattr, 0)
+//zz {
+//zz PRINT("sys_mq_getsetattr( %d, %p, %p )", ARG1,ARG2,ARG3 );
+//zz PRE_REG_READ3(long, "mq_getsetattr",
+//zz vki_mqd_t, mqdes, const struct mq_attr *, mqstat,
+//zz struct mq_attr *, omqstat);
+//zz if (!VG_(fd_allowed)(ARG1, "mq_getsetattr", tid, False)) {
+//zz SET_STATUS_( -VKI_EBADF );
+//zz } else {
+//zz if (ARG2 != 0) {
+//zz const struct vki_mq_attr *attr = (struct vki_mq_attr *)ARG2;
+//zz PRE_MEM_READ( "mq_getsetattr(mqstat->mq_flags)",
+//zz (Addr)&attr->mq_flags, sizeof(attr->mq_flags) );
+//zz }
+//zz if (ARG3 != 0)
+//zz PRE_MEM_WRITE( "mq_getsetattr(omqstat)", ARG3,
+//zz sizeof(struct vki_mq_attr) );
+//zz }
+//zz }
+//zz
+//zz POST(sys_mq_getsetattr)
+//zz {
+//zz if (ARG3 != 0)
+//zz POST_MEM_WRITE( ARG3, sizeof(struct vki_mq_attr) );
+//zz }
+//zz
+//zz PRE(sys_timer_create, 0)
+//zz {
+//zz PRINT("sys_timer_create( %d, %p, %p )", ARG1,ARG2,ARG3);
+//zz PRE_REG_READ3(long, "timer_create",
+//zz vki_clockid_t, clockid, struct sigevent *, evp,
+//zz vki_timer_t *, timerid);
+//zz if (ARG2 != 0)
+//zz PRE_MEM_READ( "timer_create(evp)", ARG2, sizeof(struct vki_sigevent) );
+//zz PRE_MEM_WRITE( "timer_create(timerid)", ARG3, sizeof(vki_timer_t) );
+//zz }
+//zz
+//zz POST(sys_timer_create)
+//zz {
+//zz POST_MEM_WRITE( ARG3, sizeof(vki_timer_t) );
+//zz }
+//zz
+//zz PRE(sys_timer_settime, 0)
+//zz {
+//zz PRINT("sys_timer_settime( %lld, %d, %p, %p )", (ULong)ARG1,ARG2,ARG3,ARG4);
+//zz PRE_REG_READ4(long, "timer_settime",
+//zz vki_timer_t, timerid, int, flags,
+//zz const struct itimerspec *, value,
+//zz struct itimerspec *, ovalue);
+//zz PRE_MEM_READ( "timer_settime(value)", ARG3,
+//zz sizeof(struct vki_itimerspec) );
+//zz if (ARG4 != 0)
+//zz PRE_MEM_WRITE( "timer_settime(ovalue)", ARG4,
+//zz sizeof(struct vki_itimerspec) );
+//zz }
+//zz
+//zz POST(sys_timer_settime)
+//zz {
+//zz if (ARG4 != 0)
+//zz POST_MEM_WRITE( ARG4, sizeof(struct vki_itimerspec) );
+//zz }
+//zz
+//zz PRE(sys_timer_gettime, 0)
+//zz {
+//zz PRINT("sys_timer_gettime( %lld, %p )", (ULong)ARG1,ARG2);
+//zz PRE_REG_READ2(long, "timer_gettime",
+//zz vki_timer_t, timerid, struct itimerspec *, value);
+//zz PRE_MEM_WRITE( "timer_gettime(value)", ARG2,
+//zz sizeof(struct vki_itimerspec));
+//zz }
+//zz
+//zz POST(sys_timer_gettime)
+//zz {
+//zz POST_MEM_WRITE( ARG2, sizeof(struct vki_itimerspec) );
+//zz }
+//zz
+//zz PRE(sys_timer_getoverrun, 0)
+//zz {
+//zz PRINT("sys_timer_getoverrun( %p )", ARG1);
+//zz PRE_REG_READ1(long, "timer_getoverrun", vki_timer_t, timerid);
+//zz }
+//zz
+//zz PRE(sys_timer_delete, 0)
+//zz {
+//zz PRINT("sys_timer_delete( %p )", ARG1);
+//zz PRE_REG_READ1(long, "timer_delete", vki_timer_t, timerid);
+//zz }
+//zz
+//zz PRE(sys_clock_settime, 0)
+//zz {
+//zz PRINT("sys_clock_settime( %d, %p )", ARG1,ARG2);
+//zz PRE_REG_READ2(long, "clock_settime",
+//zz vki_clockid_t, clk_id, const struct timespec *, tp);
+//zz PRE_MEM_READ( "clock_settime(tp)", ARG2, sizeof(struct vki_timespec) );
+//zz }
+
+PRE(sys_clock_gettime)
{
PRINT("sys_clock_gettime( %d, %p )" , ARG1,ARG2);
PRE_REG_READ2(long, "clock_gettime",
@@ -5963,250 +5568,22 @@ POST(sys_clock_gettime)
POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
}
-PRE(sys_clock_getres, 0)
-{
- PRINT("sys_clock_getres( %d, %p )" , ARG1,ARG2);
- // Nb: we can't use "RES" as the param name because that's a macro
- // defined above!
- PRE_REG_READ2(long, "clock_getres",
- vki_clockid_t, clk_id, struct timespec *, res);
- PRE_MEM_WRITE( "clock_getres(res)", ARG2, sizeof(struct vki_timespec) );
-}
-
-POST(sys_clock_getres)
-{
- POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
-}
-
-
-/* ---------------------------------------------------------------------
- Executing the syscalls
- ------------------------------------------------------------------ */
-
-static UInt bad_flags = Special;
-static void bad_before(ThreadId tid, ThreadState *tst)
-{
- VG_(message)
- (Vg_DebugMsg,"WARNING: unhandled syscall: %u", (UInt)SYSNO);
- if (VG_(clo_verbosity) > 1) {
- VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
- }
- VG_(message)
- (Vg_DebugMsg,"Do not panic. You may be able to fix this easily.");
- VG_(message)
- (Vg_DebugMsg,"Read the file README_MISSING_SYSCALL_OR_IOCTL.");
-
- SET_RESULT( -VKI_ENOSYS );
-}
-
-static const struct SyscallTableEntry bad_sys =
- { &bad_flags, bad_before, NULL };
-
-static const struct SyscallTableEntry *get_syscall_entry(UInt syscallno)
-{
- const struct SyscallTableEntry *sys;
+//zz PRE(sys_clock_getres, 0)
+//zz {
+//zz PRINT("sys_clock_getres( %d, %p )" , ARG1,ARG2);
+//zz // Nb: we can't use "RES" as the param name because that's a macro
+//zz // defined above!
+//zz PRE_REG_READ2(long, "clock_getres",
+//zz vki_clockid_t, clk_id, struct timespec *, res);
+//zz PRE_MEM_WRITE( "clock_getres(res)", ARG2, sizeof(struct vki_timespec) );
+//zz }
+//zz
+//zz POST(sys_clock_getres)
+//zz {
+//zz POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
+//zz }
- if (syscallno < VGA_(syscall_table_size) &&
- VGA_(syscall_table)[syscallno].before != NULL)
- sys = &VGA_(syscall_table)[syscallno];
- else
- sys = &bad_sys;
-
- return sys;
-}
-
-/* Perform post-syscall actions */
-void VG_(post_syscall) (ThreadId tid)
-{
- const struct SyscallTableEntry *sys;
- UInt flags;
- Bool mayBlock;
- ThreadState *tst = VG_(get_ThreadState)(tid);
- Int syscallno;
-
- vg_assert(VG_(is_running_thread)(tid));
-
- syscallno = tst->syscallno;
- tst->syscallno = -1;
-
- vg_assert(syscallno != -1);
-
- sys = get_syscall_entry(syscallno);
- flags = *(sys->flags_ptr);
-
- mayBlock = !!( flags & MayBlock );
-
- if (sys->after != NULL &&
- ((flags & PostOnFail) != 0 || !VG_(is_kerror)(RES))) {
- if (0)
- VG_(printf)("post_syscall: calling sys_after tid=%d syscallno=%d\n",
- tid, syscallno);
- (sys->after)(tid, tst);
- }
-
- /* Do any post-syscall actions
-
- NOTE: this is only called if the syscall completed. If the
- syscall was restarted, then it will call the Tool's
- pre_syscall again, without calling post_syscall (ie, more
- pre's than post's) */
- if (VG_(needs).syscall_wrapper) {
- VG_TDICT_CALL(tool_post_syscall, tid, syscallno, RES);
- }
-}
-
-/* Add and remove signals from mask so that we end up telling the
- kernel the state we actually want rather than what the client
- wants. */
-static void sanitize_client_sigmask(ThreadId tid, vki_sigset_t *mask)
-{
- VG_(sigdelset)(mask, VKI_SIGKILL);
- VG_(sigdelset)(mask, VKI_SIGSTOP);
-
- VG_(sigdelset)(mask, VKI_SIGVGKILL); /* never block */
-}
-
-void VG_(client_syscall) ( ThreadId tid )
-{
- ThreadState* tst;
- UInt syscallno, flags;
- const struct SyscallTableEntry *sys;
- Bool isSpecial = False;
- Bool mayBlock = False;
- Bool runInLWP = False;
- Bool syscall_done = False; /* we actually ran the syscall */
-
-// VGP_PUSHCC(VgpCoreSysWrap);
-
- tst = VG_(get_ThreadState)(tid);
-
- syscallno = (UInt)SYSNO;
-
- /* the syscall no is in %eax. For syscalls with <= 6 args,
- args 1 .. 6 to the syscall are in %ebx %ecx %edx %esi %edi %ebp.
- For calls with > 6 args, %ebx points to a lump of memory
- containing the args.
-
- The result is returned in %eax. If this value >= 0, the call
- succeeded, and this is the return value. If < 0, it failed, and
- the negation of this value is errno. To be more specific,
- if RES is in the range -EMEDIUMTYPE (-124) .. -EPERM (-1)
- (kernel 2.4.9 sources, include/asm-i386/errno.h)
- then it indicates an error. Otherwise it doesn't.
-
- Dirk Mueller (mueller@kde.org) says that values -4095 .. -1
- (inclusive?) indicate error returns. Not sure where the -4095
- comes from.
- */
-
- vg_assert(VG_(is_running_thread)(tid));
- vg_assert(tst->syscallno == -1);
- tst->syscallno = syscallno;
-
- /* Make sure the tmp signal mask matches the real signal
- mask; sigsuspend may change this. */
- vg_assert(VG_(iseqsigset)(&tst->sig_mask, &tst->tmp_sig_mask));
-
- sys = get_syscall_entry(syscallno);
- flags = *(sys->flags_ptr);
-
- /* !! is standard idiom to turn an int->bool */
- isSpecial = !!( flags & Special );
- mayBlock = !!( flags & MayBlock );
- // At most one of these should be true
- vg_assert( isSpecial + mayBlock <= 1 );
-
- /* Do any pre-syscall actions */
- if (VG_(needs).syscall_wrapper) {
- VG_TDICT_CALL(tool_pre_syscall, tid, syscallno);
- }
-
- PRINT("SYSCALL[%d,%d](%3d)%s%s:",
- VG_(getpid)(), tid, syscallno,
- isSpecial ? " special" : "",
- runInLWP ? " runInLWP" : "");
-
- tst->syscall_result_set = False;
-
- if (isSpecial) {
- /* "Special" syscalls are implemented by Valgrind internally,
- and do not generate real kernel calls. The expectation,
- therefore, is that the "before" function not only does the
- appropriate tests, but also performs the syscall itself and
- sets the result. Special syscalls cannot block. */
- vg_assert(!mayBlock && !runInLWP);
-
- (sys->before)(tst->tid, tst);
- /* This *must* result in tst->syscall_result_set becoming
- True. */
-
- // vg_assert(tst->sys_flags == flags);
- vg_assert(tst->syscall_result_set == True);
-
- PRINT(" --> %lld (0x%llx)\n", (Long)(Word)RES, (ULong)RES);
- syscall_done = True;
- } else {
- (sys->before)(tst->tid, tst);
- /* This *may* result in tst->syscall_result_set becoming
- True. */
-
- if (tst->syscall_result_set) {
- /* "before" decided to provide a syscall result itself, so
- don't do anything - just pretend the syscall happened. */
- PRINT(" ==> %lld (0x%llx)\n", (Long)RES, (ULong)RES);
- syscall_done = True;
- } else if (mayBlock) {
- vki_sigset_t mask;
-
- vg_assert(!(flags & PadAddr));
-
- /* Syscall may block, so run it asynchronously */
- PRINT(" --> ...\n");
-
- mask = tst->sig_mask;
- sanitize_client_sigmask(tid, &mask);
-
- VG_(set_sleeping)(tid, VgTs_WaitSys);
- VGA_(client_syscall)(syscallno, tst, &mask);
- /* VGA_(client_syscall) may not return if the syscall was
- interrupted by a signal. In that case, flow of control
- will end up back in the scheduler via the signal
- machinery. */
- VG_(set_running)(tid);
- PRINT("SYSCALL[%d,%d](%3d) --> %lld (0x%llx)\n",
- VG_(getpid)(), tid, syscallno, (Long)(Word)RES, (ULong)RES);
- } else {
- /* run the syscall directly */
- if (flags & PadAddr)
- VG_(pad_address_space)(VG_(client_end));
-
- RES = VG_(do_syscall6)(syscallno, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
- PRINT(" --> %lld (0x%llx)\n", (Long)(Word)RES, (ULong)RES);
- syscall_done = True;
- }
- }
-
- vg_assert(VG_(is_running_thread)(tid));
-
- // Tell the tool that the assignment has occurred, so it can update
- // shadow regs as necessary.
- VGP_TRACK_SYSCALL_RETVAL(tid);
-
- VG_(post_syscall)(tid);
-
- if (flags & PadAddr) {
- vg_assert(!mayBlock);
- VG_(unpad_address_space)(VG_(client_end));
- //VG_(sanity_check_memory)();
- }
-
- /* VG_(post_syscall) should set this */
- vg_assert(tst->syscallno == -1);
-
-// VGP_POPCC(VgpCoreSysWrap);
-}
/*--------------------------------------------------------------------*/
-/*--- end ---*/
+/*--- end syscalls-generic.c ---*/
/*--------------------------------------------------------------------*/
-
diff --git a/coregrind/m_syscalls/syscalls-linux.c b/coregrind/m_syscalls/syscalls-linux.c
index 2d801a1a9..c8f3bfcec 100644
--- a/coregrind/m_syscalls/syscalls-linux.c
+++ b/coregrind/m_syscalls/syscalls-linux.c
@@ -34,7 +34,11 @@
#include "pub_core_libcfile.h"
#include "pub_core_libcprint.h"
#include "pub_core_tooliface.h"
-#include "priv_syscalls.h"
+#include "pub_core_options.h"
+
+#include "priv_types_n_macros.h"
+#include "priv_syscalls-linux.h"
+
/* ---------------------------------------------------------------------
PRE/POST wrappers for arch-generic, Linux-specific syscalls
@@ -43,22 +47,29 @@
// Nb: See the comment above the generic PRE/POST wrappers in
// coregrind/vg_syscalls.c for notes about how they work.
-#define PRE(name, f) PRE_TEMPLATE( , vgOS_linux, name, f)
-#define POST(name) POST_TEMPLATE( , vgOS_linux, name)
+#define PRE(name) DEFN_PRE_TEMPLATE(linux, name)
+#define POST(name) DEFN_POST_TEMPLATE(linux, name)
-PRE(sys_exit_group, Special)
+PRE(sys_exit_group)
{
- ThreadId t;
+ ThreadId t;
+ ThreadState* tst;
PRINT("exit_group( %d )", ARG1);
PRE_REG_READ1(void, "exit_group", int, exit_code);
+ tst = VG_(get_ThreadState)(tid);
+
/* A little complex; find all the threads with the same threadgroup
as this one (including this one), and mark them to exit */
for (t = 1; t < VG_N_THREADS; t++) {
- if (VG_(threads)[t].status == VgTs_Empty || /* not alive */
- VG_(threads)[t].os_state.threadgroup != tst->os_state.threadgroup) /* not our group */
- continue;
+ if ( /* not alive */
+ VG_(threads)[t].status == VgTs_Empty
+ ||
+ /* not our group */
+ VG_(threads)[t].os_state.threadgroup != tst->os_state.threadgroup
+ )
+ continue;
VG_(threads)[t].exitreason = VgSrc_ExitSyscall;
VG_(threads)[t].os_state.exitcode = ARG1;
@@ -67,19 +78,16 @@ PRE(sys_exit_group, Special)
VG_(kill_thread)(t); /* unblock it, if blocked */
}
- /* exit_group doesn't return anything (perhaps it doesn't return?)
- Nevertheless, if we don't do this, the result-not-assigned-
- yet-you-said-you-were-Special assertion in the main syscall
- handling logic will fire. Hence ..
- */
- SET_RESULT(0);
+ /* We have to claim the syscall already succeeded. */
+ SET_STATUS_Success(0);
}
-PRE(sys_mount, MayBlock)
+PRE(sys_mount)
{
// Nb: depending on 'flags', the 'type' and 'data' args may be ignored.
// We are conservative and check everything, except the memory pointed to
// by 'data'.
+ *flags |= SfMayBlock;
PRINT( "sys_mount( %p, %p, %p, %p, %p )" ,ARG1,ARG2,ARG3,ARG4,ARG5);
PRE_REG_READ5(long, "mount",
char *, source, char *, target, char *, type,
@@ -89,21 +97,21 @@ PRE(sys_mount, MayBlock)
PRE_MEM_RASCIIZ( "mount(type)", ARG3);
}
-PRE(sys_oldumount, 0)
+PRE(sys_oldumount)
{
PRINT("sys_oldumount( %p )", ARG1);
PRE_REG_READ1(long, "umount", char *, path);
PRE_MEM_RASCIIZ( "umount(path)", ARG1);
}
-PRE(sys_umount, 0)
+PRE(sys_umount)
{
PRINT("sys_umount( %p )", ARG1);
PRE_REG_READ2(long, "umount2", char *, path, int, flags);
PRE_MEM_RASCIIZ( "umount2(path)", ARG1);
}
-PRE(sys_llseek, 0)
+PRE(sys_llseek)
{
PRINT("sys_llseek ( %d, 0x%x, 0x%x, %p, %d )", ARG1,ARG2,ARG3,ARG4,ARG5);
PRE_REG_READ5(long, "llseek",
@@ -115,641 +123,642 @@ PRE(sys_llseek, 0)
POST(sys_llseek)
{
+ vg_assert(SUCCESS);
if (RES == 0)
POST_MEM_WRITE( ARG4, sizeof(vki_loff_t) );
}
-PRE(sys_adjtimex, 0)
-{
- struct vki_timex *tx = (struct vki_timex *)ARG1;
- PRINT("sys_adjtimex ( %p )", ARG1);
- PRE_REG_READ1(long, "adjtimex", struct timex *, buf);
- PRE_MEM_READ( "adjtimex(timex->modes)", ARG1, sizeof(tx->modes));
-
-#define ADJX(bit,field) \
- if (tx->modes & bit) \
- PRE_MEM_READ( "adjtimex(timex->"#field")", \
- (Addr)&tx->field, sizeof(tx->field))
- ADJX(ADJ_FREQUENCY, freq);
- ADJX(ADJ_MAXERROR, maxerror);
- ADJX(ADJ_ESTERROR, esterror);
- ADJX(ADJ_STATUS, status);
- ADJX(ADJ_TIMECONST, constant);
- ADJX(ADJ_TICK, tick);
-#undef ADJX
-
- PRE_MEM_WRITE( "adjtimex(timex)", ARG1, sizeof(struct vki_timex));
-}
-
-POST(sys_adjtimex)
-{
- POST_MEM_WRITE( ARG1, sizeof(struct vki_timex) );
-}
-
-PRE(sys_setfsuid16, 0)
-{
- PRINT("sys_setfsuid16 ( %d )", ARG1);
- PRE_REG_READ1(long, "setfsuid16", vki_old_uid_t, uid);
-}
-
-PRE(sys_setfsuid, 0)
-{
- PRINT("sys_setfsuid ( %d )", ARG1);
- PRE_REG_READ1(long, "setfsuid", vki_uid_t, uid);
-}
-
-PRE(sys_setfsgid16, 0)
-{
- PRINT("sys_setfsgid16 ( %d )", ARG1);
- PRE_REG_READ1(long, "setfsgid16", vki_old_gid_t, gid);
-}
-
-PRE(sys_setfsgid, 0)
-{
- PRINT("sys_setfsgid ( %d )", ARG1);
- PRE_REG_READ1(long, "setfsgid", vki_gid_t, gid);
-}
-
-PRE(sys_setresuid16, 0)
-{
- PRINT("sys_setresuid16 ( %d, %d, %d )", ARG1, ARG2, ARG3);
- PRE_REG_READ3(long, "setresuid16",
- vki_old_uid_t, ruid, vki_old_uid_t, euid, vki_old_uid_t, suid);
-}
-
-PRE(sys_setresuid, 0)
-{
- PRINT("sys_setresuid ( %d, %d, %d )", ARG1, ARG2, ARG3);
- PRE_REG_READ3(long, "setresuid",
- vki_uid_t, ruid, vki_uid_t, euid, vki_uid_t, suid);
-}
-
-PRE(sys_getresuid16, 0)
-{
- PRINT("sys_getresuid16 ( %p, %p, %p )", ARG1,ARG2,ARG3);
- PRE_REG_READ3(long, "getresuid16",
- vki_old_uid_t *, ruid, vki_old_uid_t *, euid,
- vki_old_uid_t *, suid);
- PRE_MEM_WRITE( "getresuid16(ruid)", ARG1, sizeof(vki_old_uid_t) );
- PRE_MEM_WRITE( "getresuid16(euid)", ARG2, sizeof(vki_old_uid_t) );
- PRE_MEM_WRITE( "getresuid16(suid)", ARG3, sizeof(vki_old_uid_t) );
-}
-
-POST(sys_getresuid16)
-{
- if (RES == 0) {
- POST_MEM_WRITE( ARG1, sizeof(vki_old_uid_t) );
- POST_MEM_WRITE( ARG2, sizeof(vki_old_uid_t) );
- POST_MEM_WRITE( ARG3, sizeof(vki_old_uid_t) );
- }
-}
-
-PRE(sys_getresuid, 0)
-{
- PRINT("sys_getresuid ( %p, %p, %p )", ARG1,ARG2,ARG3);
- PRE_REG_READ3(long, "getresuid",
- vki_uid_t *, ruid, vki_uid_t *, euid, vki_uid_t *, suid);
- PRE_MEM_WRITE( "getresuid(ruid)", ARG1, sizeof(vki_uid_t) );
- PRE_MEM_WRITE( "getresuid(euid)", ARG2, sizeof(vki_uid_t) );
- PRE_MEM_WRITE( "getresuid(suid)", ARG3, sizeof(vki_uid_t) );
-}
-
-POST(sys_getresuid)
-{
- if (RES == 0) {
- POST_MEM_WRITE( ARG1, sizeof(vki_uid_t) );
- POST_MEM_WRITE( ARG2, sizeof(vki_uid_t) );
- POST_MEM_WRITE( ARG3, sizeof(vki_uid_t) );
- }
-}
-
-PRE(sys_setresgid16, 0)
-{
- PRINT("sys_setresgid16 ( %d, %d, %d )", ARG1, ARG2, ARG3);
- PRE_REG_READ3(long, "setresgid16",
- vki_old_gid_t, rgid, vki_old_gid_t, egid, vki_old_gid_t, sgid);
-}
-
-PRE(sys_setresgid, 0)
-{
- PRINT("sys_setresgid ( %d, %d, %d )", ARG1, ARG2, ARG3);
- PRE_REG_READ3(long, "setresgid",
- vki_gid_t, rgid, vki_gid_t, egid, vki_gid_t, sgid);
-}
-
-PRE(sys_getresgid16, 0)
-{
- PRINT("sys_getresgid16 ( %p, %p, %p )", ARG1,ARG2,ARG3);
- PRE_REG_READ3(long, "getresgid16",
- vki_old_gid_t *, rgid, vki_old_gid_t *, egid,
- vki_old_gid_t *, sgid);
- PRE_MEM_WRITE( "getresgid16(rgid)", ARG1, sizeof(vki_old_gid_t) );
- PRE_MEM_WRITE( "getresgid16(egid)", ARG2, sizeof(vki_old_gid_t) );
- PRE_MEM_WRITE( "getresgid16(sgid)", ARG3, sizeof(vki_old_gid_t) );
-}
-
-POST(sys_getresgid16)
-{
- if (RES == 0) {
- POST_MEM_WRITE( ARG1, sizeof(vki_old_gid_t) );
- POST_MEM_WRITE( ARG2, sizeof(vki_old_gid_t) );
- POST_MEM_WRITE( ARG3, sizeof(vki_old_gid_t) );
- }
-}
-
-PRE(sys_getresgid, 0)
-{
- PRINT("sys_getresgid ( %p, %p, %p )", ARG1,ARG2,ARG3);
- PRE_REG_READ3(long, "getresgid",
- vki_gid_t *, rgid, vki_gid_t *, egid, vki_gid_t *, sgid);
- PRE_MEM_WRITE( "getresgid(rgid)", ARG1, sizeof(vki_gid_t) );
- PRE_MEM_WRITE( "getresgid(egid)", ARG2, sizeof(vki_gid_t) );
- PRE_MEM_WRITE( "getresgid(sgid)", ARG3, sizeof(vki_gid_t) );
-}
-
-POST(sys_getresgid)
-{
- if (RES == 0) {
- POST_MEM_WRITE( ARG1, sizeof(vki_gid_t) );
- POST_MEM_WRITE( ARG2, sizeof(vki_gid_t) );
- POST_MEM_WRITE( ARG3, sizeof(vki_gid_t) );
- }
-}
-
-PRE(sys_ioperm, 0)
-{
- PRINT("sys_ioperm ( %d, %d, %d )", ARG1, ARG2, ARG3 );
- PRE_REG_READ3(long, "ioperm",
- unsigned long, from, unsigned long, num, int, turn_on);
-}
-
-PRE(sys_syslog, MayBlock)
-{
- PRINT("sys_syslog (%d, %p, %d)", ARG1,ARG2,ARG3);
- PRE_REG_READ3(long, "syslog", int, type, char *, bufp, int, len);
- switch (ARG1) {
- // The kernel uses magic numbers here, rather than named constants,
- // therefore so do we.
- case 2: case 3: case 4:
- PRE_MEM_WRITE( "syslog(bufp)", ARG2, ARG3);
- break;
- default:
- break;
- }
-}
-
-POST(sys_syslog)
-{
- switch (ARG1) {
- case 2: case 3: case 4:
- POST_MEM_WRITE( ARG2, ARG3 );
- break;
- default:
- break;
- }
-}
-
-PRE(sys_vhangup, 0)
-{
- PRINT("sys_vhangup ( )");
- PRE_REG_READ0(long, "vhangup");
-}
-
-PRE(sys_sysinfo, 0)
-{
- PRINT("sys_sysinfo ( %p )",ARG1);
- PRE_REG_READ1(long, "sysinfo", struct sysinfo *, info);
- PRE_MEM_WRITE( "sysinfo(info)", ARG1, sizeof(struct vki_sysinfo) );
-}
-
-POST(sys_sysinfo)
-{
- POST_MEM_WRITE( ARG1, sizeof(struct vki_sysinfo) );
-}
-
-PRE(sys_personality, 0)
-{
- PRINT("sys_personality ( %llu )", (ULong)ARG1);
- PRE_REG_READ1(long, "personality", vki_u_long, persona);
-}
-
-PRE(sys_sysctl, 0)
-{
- struct __vki_sysctl_args *args;
+//zz PRE(sys_adjtimex, 0)
+//zz {
+//zz struct vki_timex *tx = (struct vki_timex *)ARG1;
+//zz PRINT("sys_adjtimex ( %p )", ARG1);
+//zz PRE_REG_READ1(long, "adjtimex", struct timex *, buf);
+//zz PRE_MEM_READ( "adjtimex(timex->modes)", ARG1, sizeof(tx->modes));
+//zz
+//zz #define ADJX(bit,field) \
+//zz if (tx->modes & bit) \
+//zz PRE_MEM_READ( "adjtimex(timex->"#field")", \
+//zz (Addr)&tx->field, sizeof(tx->field))
+//zz ADJX(ADJ_FREQUENCY, freq);
+//zz ADJX(ADJ_MAXERROR, maxerror);
+//zz ADJX(ADJ_ESTERROR, esterror);
+//zz ADJX(ADJ_STATUS, status);
+//zz ADJX(ADJ_TIMECONST, constant);
+//zz ADJX(ADJ_TICK, tick);
+//zz #undef ADJX
+//zz
+//zz PRE_MEM_WRITE( "adjtimex(timex)", ARG1, sizeof(struct vki_timex));
+//zz }
+//zz
+//zz POST(sys_adjtimex)
+//zz {
+//zz POST_MEM_WRITE( ARG1, sizeof(struct vki_timex) );
+//zz }
+//zz
+//zz PRE(sys_setfsuid16, 0)
+//zz {
+//zz PRINT("sys_setfsuid16 ( %d )", ARG1);
+//zz PRE_REG_READ1(long, "setfsuid16", vki_old_uid_t, uid);
+//zz }
+//zz
+//zz PRE(sys_setfsuid, 0)
+//zz {
+//zz PRINT("sys_setfsuid ( %d )", ARG1);
+//zz PRE_REG_READ1(long, "setfsuid", vki_uid_t, uid);
+//zz }
+//zz
+//zz PRE(sys_setfsgid16, 0)
+//zz {
+//zz PRINT("sys_setfsgid16 ( %d )", ARG1);
+//zz PRE_REG_READ1(long, "setfsgid16", vki_old_gid_t, gid);
+//zz }
+//zz
+//zz PRE(sys_setfsgid, 0)
+//zz {
+//zz PRINT("sys_setfsgid ( %d )", ARG1);
+//zz PRE_REG_READ1(long, "setfsgid", vki_gid_t, gid);
+//zz }
+//zz
+//zz PRE(sys_setresuid16, 0)
+//zz {
+//zz PRINT("sys_setresuid16 ( %d, %d, %d )", ARG1, ARG2, ARG3);
+//zz PRE_REG_READ3(long, "setresuid16",
+//zz vki_old_uid_t, ruid, vki_old_uid_t, euid, vki_old_uid_t, suid);
+//zz }
+//zz
+//zz PRE(sys_setresuid, 0)
+//zz {
+//zz PRINT("sys_setresuid ( %d, %d, %d )", ARG1, ARG2, ARG3);
+//zz PRE_REG_READ3(long, "setresuid",
+//zz vki_uid_t, ruid, vki_uid_t, euid, vki_uid_t, suid);
+//zz }
+//zz
+//zz PRE(sys_getresuid16, 0)
+//zz {
+//zz PRINT("sys_getresuid16 ( %p, %p, %p )", ARG1,ARG2,ARG3);
+//zz PRE_REG_READ3(long, "getresuid16",
+//zz vki_old_uid_t *, ruid, vki_old_uid_t *, euid,
+//zz vki_old_uid_t *, suid);
+//zz PRE_MEM_WRITE( "getresuid16(ruid)", ARG1, sizeof(vki_old_uid_t) );
+//zz PRE_MEM_WRITE( "getresuid16(euid)", ARG2, sizeof(vki_old_uid_t) );
+//zz PRE_MEM_WRITE( "getresuid16(suid)", ARG3, sizeof(vki_old_uid_t) );
+//zz }
+//zz
+//zz POST(sys_getresuid16)
+//zz {
+//zz if (RES == 0) {
+//zz POST_MEM_WRITE( ARG1, sizeof(vki_old_uid_t) );
+//zz POST_MEM_WRITE( ARG2, sizeof(vki_old_uid_t) );
+//zz POST_MEM_WRITE( ARG3, sizeof(vki_old_uid_t) );
+//zz }
+//zz }
+//zz
+//zz PRE(sys_getresuid, 0)
+//zz {
+//zz PRINT("sys_getresuid ( %p, %p, %p )", ARG1,ARG2,ARG3);
+//zz PRE_REG_READ3(long, "getresuid",
+//zz vki_uid_t *, ruid, vki_uid_t *, euid, vki_uid_t *, suid);
+//zz PRE_MEM_WRITE( "getresuid(ruid)", ARG1, sizeof(vki_uid_t) );
+//zz PRE_MEM_WRITE( "getresuid(euid)", ARG2, sizeof(vki_uid_t) );
+//zz PRE_MEM_WRITE( "getresuid(suid)", ARG3, sizeof(vki_uid_t) );
+//zz }
+//zz
+//zz POST(sys_getresuid)
+//zz {
+//zz if (RES == 0) {
+//zz POST_MEM_WRITE( ARG1, sizeof(vki_uid_t) );
+//zz POST_MEM_WRITE( ARG2, sizeof(vki_uid_t) );
+//zz POST_MEM_WRITE( ARG3, sizeof(vki_uid_t) );
+//zz }
+//zz }
+//zz
+//zz PRE(sys_setresgid16, 0)
+//zz {
+//zz PRINT("sys_setresgid16 ( %d, %d, %d )", ARG1, ARG2, ARG3);
+//zz PRE_REG_READ3(long, "setresgid16",
+//zz vki_old_gid_t, rgid, vki_old_gid_t, egid, vki_old_gid_t, sgid);
+//zz }
+//zz
+//zz PRE(sys_setresgid, 0)
+//zz {
+//zz PRINT("sys_setresgid ( %d, %d, %d )", ARG1, ARG2, ARG3);
+//zz PRE_REG_READ3(long, "setresgid",
+//zz vki_gid_t, rgid, vki_gid_t, egid, vki_gid_t, sgid);
+//zz }
+//zz
+//zz PRE(sys_getresgid16, 0)
+//zz {
+//zz PRINT("sys_getresgid16 ( %p, %p, %p )", ARG1,ARG2,ARG3);
+//zz PRE_REG_READ3(long, "getresgid16",
+//zz vki_old_gid_t *, rgid, vki_old_gid_t *, egid,
+//zz vki_old_gid_t *, sgid);
+//zz PRE_MEM_WRITE( "getresgid16(rgid)", ARG1, sizeof(vki_old_gid_t) );
+//zz PRE_MEM_WRITE( "getresgid16(egid)", ARG2, sizeof(vki_old_gid_t) );
+//zz PRE_MEM_WRITE( "getresgid16(sgid)", ARG3, sizeof(vki_old_gid_t) );
+//zz }
+//zz
+//zz POST(sys_getresgid16)
+//zz {
+//zz if (RES == 0) {
+//zz POST_MEM_WRITE( ARG1, sizeof(vki_old_gid_t) );
+//zz POST_MEM_WRITE( ARG2, sizeof(vki_old_gid_t) );
+//zz POST_MEM_WRITE( ARG3, sizeof(vki_old_gid_t) );
+//zz }
+//zz }
+//zz
+//zz PRE(sys_getresgid, 0)
+//zz {
+//zz PRINT("sys_getresgid ( %p, %p, %p )", ARG1,ARG2,ARG3);
+//zz PRE_REG_READ3(long, "getresgid",
+//zz vki_gid_t *, rgid, vki_gid_t *, egid, vki_gid_t *, sgid);
+//zz PRE_MEM_WRITE( "getresgid(rgid)", ARG1, sizeof(vki_gid_t) );
+//zz PRE_MEM_WRITE( "getresgid(egid)", ARG2, sizeof(vki_gid_t) );
+//zz PRE_MEM_WRITE( "getresgid(sgid)", ARG3, sizeof(vki_gid_t) );
+//zz }
+//zz
+//zz POST(sys_getresgid)
+//zz {
+//zz if (RES == 0) {
+//zz POST_MEM_WRITE( ARG1, sizeof(vki_gid_t) );
+//zz POST_MEM_WRITE( ARG2, sizeof(vki_gid_t) );
+//zz POST_MEM_WRITE( ARG3, sizeof(vki_gid_t) );
+//zz }
+//zz }
+//zz
+//zz PRE(sys_ioperm, 0)
+//zz {
+//zz PRINT("sys_ioperm ( %d, %d, %d )", ARG1, ARG2, ARG3 );
+//zz PRE_REG_READ3(long, "ioperm",
+//zz unsigned long, from, unsigned long, num, int, turn_on);
+//zz }
+//zz
+//zz PRE(sys_syslog, MayBlock)
+//zz {
+//zz PRINT("sys_syslog (%d, %p, %d)", ARG1,ARG2,ARG3);
+//zz PRE_REG_READ3(long, "syslog", int, type, char *, bufp, int, len);
+//zz switch (ARG1) {
+//zz // The kernel uses magic numbers here, rather than named constants,
+//zz // therefore so do we.
+//zz case 2: case 3: case 4:
+//zz PRE_MEM_WRITE( "syslog(bufp)", ARG2, ARG3);
+//zz break;
+//zz default:
+//zz break;
+//zz }
+//zz }
+//zz
+//zz POST(sys_syslog)
+//zz {
+//zz switch (ARG1) {
+//zz case 2: case 3: case 4:
+//zz POST_MEM_WRITE( ARG2, ARG3 );
+//zz break;
+//zz default:
+//zz break;
+//zz }
+//zz }
+//zz
+//zz PRE(sys_vhangup, 0)
+//zz {
+//zz PRINT("sys_vhangup ( )");
+//zz PRE_REG_READ0(long, "vhangup");
+//zz }
+//zz
+//zz PRE(sys_sysinfo, 0)
+//zz {
+//zz PRINT("sys_sysinfo ( %p )",ARG1);
+//zz PRE_REG_READ1(long, "sysinfo", struct sysinfo *, info);
+//zz PRE_MEM_WRITE( "sysinfo(info)", ARG1, sizeof(struct vki_sysinfo) );
+//zz }
+//zz
+//zz POST(sys_sysinfo)
+//zz {
+//zz POST_MEM_WRITE( ARG1, sizeof(struct vki_sysinfo) );
+//zz }
+//zz
+//zz PRE(sys_personality, 0)
+//zz {
+//zz PRINT("sys_personality ( %llu )", (ULong)ARG1);
+//zz PRE_REG_READ1(long, "personality", vki_u_long, persona);
+//zz }
+
+PRE(sys_sysctl)
+{
+ struct __vki_sysctl_args *argz;
PRINT("sys_sysctl ( %p )", ARG1 );
- args = (struct __vki_sysctl_args *)ARG1;
- PRE_REG_READ1(long, "sysctl", struct __sysctl_args *, args);
+ argz = (struct __vki_sysctl_args *)ARG1;
+ PRE_REG_READ1(long, "sysctl", struct __sysctl_args *, argz);
PRE_MEM_WRITE( "sysctl(args)", ARG1, sizeof(struct __vki_sysctl_args) );
if (!VG_(is_addressable)(ARG1, sizeof(struct __vki_sysctl_args), VKI_PROT_READ)) {
- SET_RESULT( -VKI_EFAULT );
+ SET_STATUS_Failure( VKI_EFAULT );
return;
}
- PRE_MEM_READ("sysctl(name)", (Addr)args->name, args->nlen * sizeof(*args->name));
- if (args->newval != NULL)
- PRE_MEM_READ("sysctl(newval)", (Addr)args->newval, args->newlen);
- if (args->oldlenp != NULL) {
- PRE_MEM_READ("sysctl(oldlenp)", (Addr)args->oldlenp, sizeof(*args->oldlenp));
- PRE_MEM_WRITE("sysctl(oldval)", (Addr)args->oldval, *args->oldlenp);
+ PRE_MEM_READ("sysctl(name)", (Addr)argz->name, argz->nlen * sizeof(*argz->name));
+ if (argz->newval != NULL)
+ PRE_MEM_READ("sysctl(newval)", (Addr)argz->newval, argz->newlen);
+ if (argz->oldlenp != NULL) {
+ PRE_MEM_READ("sysctl(oldlenp)", (Addr)argz->oldlenp, sizeof(*argz->oldlenp));
+ PRE_MEM_WRITE("sysctl(oldval)", (Addr)argz->oldval, *argz->oldlenp);
}
}
POST(sys_sysctl)
{
- struct __vki_sysctl_args *args;
- args = (struct __vki_sysctl_args *)ARG1;
- if (args->oldlenp != NULL) {
- POST_MEM_WRITE((Addr)args->oldlenp, sizeof(*args->oldlenp));
- POST_MEM_WRITE((Addr)args->oldval, 1 + *args->oldlenp);
- }
-}
-
-PRE(sys_prctl, MayBlock)
-{
- PRINT( "prctl ( %d, %d, %d, %d, %d )", ARG1, ARG2, ARG3, ARG4, ARG5 );
- // XXX: too simplistic, often not all args are used
- // Nb: can't use "ARG2".."ARG5" here because that's our own macro...
- PRE_REG_READ5(long, "prctl",
- int, option, unsigned long, arg2, unsigned long, arg3,
- unsigned long, arg4, unsigned long, arg5);
- // XXX: totally wrong... we need to look at the 'option' arg, and do
- // PRE_MEM_READs/PRE_MEM_WRITEs as necessary...
-}
-
-PRE(sys_sendfile, MayBlock)
-{
- PRINT("sys_sendfile ( %d, %d, %p, %llu )", ARG1,ARG2,ARG3,(ULong)ARG4);
- PRE_REG_READ4(ssize_t, "sendfile",
- int, out_fd, int, in_fd, vki_off_t *, offset,
- vki_size_t, count);
- if (ARG3 != 0)
- PRE_MEM_WRITE( "sendfile(offset)", ARG3, sizeof(vki_off_t) );
-}
-
-POST(sys_sendfile)
-{
- POST_MEM_WRITE( ARG3, sizeof( vki_off_t ) );
-}
-
-PRE(sys_sendfile64, MayBlock)
-{
- PRINT("sendfile64 ( %d, %d, %p, %llu )",ARG1,ARG2,ARG3,(ULong)ARG4);
- PRE_REG_READ4(ssize_t, "sendfile64",
- int, out_fd, int, in_fd, vki_loff_t *, offset,
- vki_size_t, count);
- if (ARG3 != 0)
- PRE_MEM_WRITE( "sendfile64(offset)", ARG3, sizeof(vki_loff_t) );
-}
-
-POST(sys_sendfile64)
-{
- if (ARG3 != 0 ) {
- POST_MEM_WRITE( ARG3, sizeof(vki_loff_t) );
- }
-}
-
-PRE(sys_futex, MayBlock)
-{
- /*
- arg param used by ops
-
- ARG1 - u32 *futex all
- ARG2 - int op
- ARG3 - int val WAIT,WAKE,FD,REQUEUE,CMP_REQUEUE
- ARG4 - struct timespec *utime WAIT:time* REQUEUE,CMP_REQUEUE:val2
- ARG5 - u32 *uaddr2 REQUEUE,CMP_REQUEUE
- ARG6 - int val3 CMP_REQUEUE
- */
- PRINT("sys_futex ( %p, %d, %d, %p, %p )", ARG1,ARG2,ARG3,ARG4,ARG5);
- PRE_REG_READ6(long, "futex",
- vki_u32 *, futex, int, op, int, val,
- struct timespec *, utime, vki_u32 *, uaddr2, int, val3);
-
- PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
-
- switch(ARG2) {
- case VKI_FUTEX_WAIT:
- if (ARG4 != 0)
- PRE_MEM_READ( "futex(timeout)", ARG4, sizeof(struct vki_timespec) );
- break;
-
- case VKI_FUTEX_REQUEUE:
- case VKI_FUTEX_CMP_REQUEUE:
- PRE_MEM_READ( "futex(futex2)", ARG5, sizeof(Int) );
- break;
-
- case VKI_FUTEX_WAKE:
- case VKI_FUTEX_FD:
- /* no additional pointers */
- break;
-
- default:
- SET_RESULT(-VKI_ENOSYS); // some futex function we don't understand
- break;
- }
-}
-
-POST(sys_futex)
-{
- POST_MEM_WRITE( ARG1, sizeof(int) );
- if (ARG2 == VKI_FUTEX_FD) {
- if (!VG_(fd_allowed)(RES, "futex", tid, True)) {
- VG_(close)(RES);
- SET_RESULT( -VKI_EMFILE );
- } else {
- if (VG_(clo_track_fds))
- VG_(record_fd_open)(tid, RES, VG_(arena_strdup)(VG_AR_CORE, (Char*)ARG1));
- }
- }
-}
-
-PRE(sys_epoll_create, 0)
-{
- PRINT("sys_epoll_create ( %d )", ARG1);
- PRE_REG_READ1(long, "epoll_create", int, size);
-}
-
-POST(sys_epoll_create)
-{
- if (!VG_(fd_allowed)(RES, "epoll_create", tid, True)) {
- VG_(close)(RES);
- SET_RESULT( -VKI_EMFILE );
- } else {
- if (VG_(clo_track_fds))
- VG_(record_fd_open) (tid, RES, NULL);
- }
-}
-
-PRE(sys_epoll_ctl, 0)
-{
- static const char* epoll_ctl_s[3] = {
- "EPOLL_CTL_ADD",
- "EPOLL_CTL_DEL",
- "EPOLL_CTL_MOD"
- };
- PRINT("sys_epoll_ctl ( %d, %s, %d, %p )",
- ARG1, ( ARG2<3 ? epoll_ctl_s[ARG2] : "?" ), ARG3, ARG4);
- PRE_REG_READ4(long, "epoll_ctl",
- int, epfd, int, op, int, fd, struct epoll_event *, event);
- PRE_MEM_READ( "epoll_ctl(event)", ARG4, sizeof(struct epoll_event) );
-}
-
-PRE(sys_epoll_wait, MayBlock)
-{
- PRINT("sys_epoll_wait ( %d, %p, %d, %d )", ARG1, ARG2, ARG3, ARG4);
- PRE_REG_READ4(long, "epoll_wait",
- int, epfd, struct epoll_event *, events,
- int, maxevents, int, timeout);
- PRE_MEM_WRITE( "epoll_wait(events)", ARG2, sizeof(struct epoll_event)*ARG3);
-}
-
-POST(sys_epoll_wait)
-{
- if (RES > 0)
- POST_MEM_WRITE( ARG2, sizeof(struct epoll_event)*RES ) ;
-}
-
-PRE(sys_gettid, 0)
-{
- PRINT("sys_gettid ()");
- PRE_REG_READ0(long, "gettid");
-}
-
-PRE(sys_tkill, Special)
-{
- /* int tkill(pid_t tid, int sig); */
- PRINT("sys_tkill ( %d, %d )", ARG1,ARG2);
- PRE_REG_READ2(long, "tkill", int, tid, int, sig);
- if (!VG_(client_signal_OK)(ARG2)) {
- SET_RESULT( -VKI_EINVAL );
- return;
- }
-
- /* If we're sending SIGKILL, check to see if the target is one of
- our threads and handle it specially. */
- if (ARG2 == VKI_SIGKILL && VG_(do_sigkill)(ARG1, -1))
- SET_RESULT(0);
- else
- SET_RESULT(VG_(do_syscall2)(SYSNO, ARG1, ARG2));
-
- if (VG_(clo_trace_signals))
- VG_(message)(Vg_DebugMsg, "tkill: sent signal %d to pid %d",
- ARG2, ARG1);
- // Check to see if this kill gave us a pending signal
- VG_(poll_signals)(tid);
-}
-
-PRE(sys_tgkill, Special)
-{
- /* int tgkill(pid_t tgid, pid_t tid, int sig); */
- PRINT("sys_tgkill ( %d, %d, %d )", ARG1,ARG2,ARG3);
- PRE_REG_READ3(long, "tgkill", int, tgid, int, tid, int, sig);
- if (!VG_(client_signal_OK)(ARG3)) {
- SET_RESULT( -VKI_EINVAL );
- return;
- }
-
- /* If we're sending SIGKILL, check to see if the target is one of
- our threads and handle it specially. */
- if (ARG3 == VKI_SIGKILL && VG_(do_sigkill)(ARG2, ARG1))
- SET_RESULT(0);
- else
- SET_RESULT(VG_(do_syscall3)(SYSNO, ARG1, ARG2, ARG3));
-
- if (VG_(clo_trace_signals))
- VG_(message)(Vg_DebugMsg, "tgkill: sent signal %d to pid %d/%d",
- ARG3, ARG1, ARG2);
- // Check to see if this kill gave us a pending signal
- VG_(poll_signals)(tid);
-}
-
-POST(sys_tgkill)
-{
- if (VG_(clo_trace_signals))
- VG_(message)(Vg_DebugMsg, "tgkill: sent signal %d to pid %d/%d",
- ARG3, ARG1, ARG2);
- // Check to see if this kill gave us a pending signal
- VG_(poll_signals)(tid);
-}
-
-PRE(sys_fadvise64, 0)
-{
- PRINT("sys_fadvise64 ( %d, %lld, %lu, %d )", ARG1,ARG2,ARG3);
- PRE_REG_READ4(long, "fadvise64",
- int, fd, vki_loff_t, offset, vki_size_t, len, int, advice)
-}
-
-PRE(sys_fadvise64_64, 0)
-{
- PRINT("sys_fadvise64_64 ( %d, %lld, %lld, %d )", ARG1,ARG2,ARG3);
- PRE_REG_READ4(long, "fadvise64_64",
- int, fd, vki_loff_t, offset, vki_loff_t, len, int, advice)
-}
-
-// Nb: this wrapper is "Special" because we have to pad/unpad memory around
-// the syscall itself, and this allows us to control exactly the code that
-// gets run while the padding is in place.
-PRE(sys_io_setup, Special)
-{
- SizeT size;
- Addr addr;
-
- PRINT("sys_io_setup ( %u, %p )", ARG1,ARG2);
- PRE_REG_READ2(long, "io_setup",
- unsigned, nr_events, vki_aio_context_t *, ctxp);
- PRE_MEM_WRITE( "io_setup(ctxp)", ARG2, sizeof(vki_aio_context_t) );
-
- size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) +
- ARG1*sizeof(struct vki_io_event));
- addr = VG_(find_map_space)(0, size, True);
-
- if (addr == 0) {
- SET_RESULT( -VKI_ENOMEM );
- return;
- }
-
- VG_(map_segment)(addr, size, VKI_PROT_READ|VKI_PROT_WRITE, SF_FIXED);
-
- VG_(pad_address_space)(0);
- SET_RESULT( VG_(do_syscall2)(SYSNO, ARG1, ARG2) );
- VG_(unpad_address_space)(0);
-
- if (RES == 0) {
- struct vki_aio_ring *r = *(struct vki_aio_ring **)ARG2;
-
- vg_assert(addr == (Addr)r);
- vg_assert(VG_(valid_client_addr)(addr, size, tid, "io_setup"));
-
- VG_TRACK( new_mem_mmap, addr, size, True, True, False );
- POST_MEM_WRITE( ARG2, sizeof(vki_aio_context_t) );
- }
- else {
- VG_(unmap_range)(addr, size);
- }
-}
-
-// Nb: This wrapper is "Special" because we need 'size' to do the unmap
-// after the syscall. We must get 'size' from the aio_ring structure,
-// before the syscall, while the aio_ring structure still exists. (And we
-// know that we must look at the aio_ring structure because Tom inspected the
-// kernel and glibc sources to see what they do, yuk.)
-//
-// XXX This segment can be implicitly unmapped when aio
-// file-descriptors are closed...
-PRE(sys_io_destroy, Special)
-{
- Segment *s = VG_(find_segment)(ARG1);
- struct vki_aio_ring *r;
- SizeT size;
-
- PRINT("sys_io_destroy ( %llu )", (ULong)ARG1);
- PRE_REG_READ1(long, "io_destroy", vki_aio_context_t, ctx);
-
- // If we are going to seg fault (due to a bogus ARG1) do it as late as
- // possible...
- r = *(struct vki_aio_ring **)ARG1;
- size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) +
- r->nr*sizeof(struct vki_io_event));
-
- SET_RESULT( VG_(do_syscall1)(SYSNO, ARG1) );
-
- if (RES == 0 && s != NULL) {
- VG_TRACK( die_mem_munmap, ARG1, size );
- VG_(unmap_range)(ARG1, size);
- }
-}
-
-PRE(sys_io_getevents, MayBlock)
-{
- PRINT("sys_io_getevents ( %llu, %lld, %lld, %p, %p )",
- (ULong)ARG1,(Long)ARG2,(Long)ARG3,ARG4,ARG5);
- PRE_REG_READ5(long, "io_getevents",
- vki_aio_context_t, ctx_id, long, min_nr, long, nr,
- struct io_event *, events,
- struct timespec *, timeout);
- if (ARG3 > 0)
- PRE_MEM_WRITE( "io_getevents(events)",
- ARG4, sizeof(struct vki_io_event)*ARG3 );
- if (ARG5 != 0)
- PRE_MEM_READ( "io_getevents(timeout)",
- ARG5, sizeof(struct vki_timespec));
-}
-
-POST(sys_io_getevents)
-{
- int i;
-
- if (RES > 0) {
- POST_MEM_WRITE( ARG4, sizeof(struct vki_io_event)*RES );
- for (i = 0; i < RES; i++) {
- const struct vki_io_event *vev = ((struct vki_io_event *)ARG4) + i;
- const struct vki_iocb *cb = (struct vki_iocb *)(Addr)vev->obj;
-
- switch (cb->aio_lio_opcode) {
- case VKI_IOCB_CMD_PREAD:
- if (vev->result > 0)
- POST_MEM_WRITE( cb->aio_buf, vev->result );
- break;
-
- case VKI_IOCB_CMD_PWRITE:
- break;
-
- default:
- VG_(message)(Vg_DebugMsg,"Warning: unhandled io_getevents opcode: %u\n",cb->aio_lio_opcode);
- break;
- }
- }
+ struct __vki_sysctl_args *argz;
+ argz = (struct __vki_sysctl_args *)ARG1;
+ if (argz->oldlenp != NULL) {
+ POST_MEM_WRITE((Addr)argz->oldlenp, sizeof(*argz->oldlenp));
+ POST_MEM_WRITE((Addr)argz->oldval, 1 + *argz->oldlenp);
}
}
-PRE(sys_io_submit, 0)
-{
- int i;
-
- PRINT("sys_io_submit( %llu, %lld, %p )", (ULong)ARG1,(Long)ARG2,ARG3);
- PRE_REG_READ3(long, "io_submit",
- vki_aio_context_t, ctx_id, long, nr,
- struct iocb **, iocbpp);
- PRE_MEM_READ( "io_submit(iocbpp)", ARG3, ARG2*sizeof(struct vki_iocb *) );
- if (ARG3 != 0) {
- for (i = 0; i < ARG2; i++) {
- struct vki_iocb *cb = ((struct vki_iocb **)ARG3)[i];
- PRE_MEM_READ( "io_submit(iocb)", (Addr)cb, sizeof(struct vki_iocb) );
- switch (cb->aio_lio_opcode) {
- case VKI_IOCB_CMD_PREAD:
- PRE_MEM_WRITE( "io_submit(PREAD)", cb->aio_buf, cb->aio_nbytes );
- break;
-
- case VKI_IOCB_CMD_PWRITE:
- PRE_MEM_READ( "io_submit(PWRITE)", cb->aio_buf, cb->aio_nbytes );
- break;
-
- default:
- VG_(message)(Vg_DebugMsg,"Warning: unhandled io_submit opcode: %u\n",
- cb->aio_lio_opcode);
- break;
- }
- }
- }
-}
-
-PRE(sys_io_cancel, 0)
-{
- PRINT("sys_io_cancel( %llu, %p, %p )", (ULong)ARG1,ARG2,ARG3);
- PRE_REG_READ3(long, "io_cancel",
- vki_aio_context_t, ctx_id, struct iocb *, iocb,
- struct io_event *, result);
- PRE_MEM_READ( "io_cancel(iocb)", ARG2, sizeof(struct vki_iocb) );
- PRE_MEM_WRITE( "io_cancel(result)", ARG3, sizeof(struct vki_io_event) );
-}
-
-POST(sys_io_cancel)
-{
- POST_MEM_WRITE( ARG3, sizeof(struct vki_io_event) );
-}
-
-#undef PRE
-#undef POST
+//zz PRE(sys_prctl, MayBlock)
+//zz {
+//zz PRINT( "prctl ( %d, %d, %d, %d, %d )", ARG1, ARG2, ARG3, ARG4, ARG5 );
+//zz // XXX: too simplistic, often not all args are used
+//zz // Nb: can't use "ARG2".."ARG5" here because that's our own macro...
+//zz PRE_REG_READ5(long, "prctl",
+//zz int, option, unsigned long, arg2, unsigned long, arg3,
+//zz unsigned long, arg4, unsigned long, arg5);
+//zz // XXX: totally wrong... we need to look at the 'option' arg, and do
+//zz // PRE_MEM_READs/PRE_MEM_WRITEs as necessary...
+//zz }
+//zz
+//zz PRE(sys_sendfile, MayBlock)
+//zz {
+//zz PRINT("sys_sendfile ( %d, %d, %p, %llu )", ARG1,ARG2,ARG3,(ULong)ARG4);
+//zz PRE_REG_READ4(ssize_t, "sendfile",
+//zz int, out_fd, int, in_fd, vki_off_t *, offset,
+//zz vki_size_t, count);
+//zz if (ARG3 != 0)
+//zz PRE_MEM_WRITE( "sendfile(offset)", ARG3, sizeof(vki_off_t) );
+//zz }
+//zz
+//zz POST(sys_sendfile)
+//zz {
+//zz POST_MEM_WRITE( ARG3, sizeof( vki_off_t ) );
+//zz }
+//zz
+//zz PRE(sys_sendfile64, MayBlock)
+//zz {
+//zz PRINT("sendfile64 ( %d, %d, %p, %llu )",ARG1,ARG2,ARG3,(ULong)ARG4);
+//zz PRE_REG_READ4(ssize_t, "sendfile64",
+//zz int, out_fd, int, in_fd, vki_loff_t *, offset,
+//zz vki_size_t, count);
+//zz if (ARG3 != 0)
+//zz PRE_MEM_WRITE( "sendfile64(offset)", ARG3, sizeof(vki_loff_t) );
+//zz }
+//zz
+//zz POST(sys_sendfile64)
+//zz {
+//zz if (ARG3 != 0 ) {
+//zz POST_MEM_WRITE( ARG3, sizeof(vki_loff_t) );
+//zz }
+//zz }
+//zz
+//zz PRE(sys_futex, MayBlock)
+//zz {
+//zz /*
+//zz arg param used by ops
+//zz
+//zz ARG1 - u32 *futex all
+//zz ARG2 - int op
+//zz ARG3 - int val WAIT,WAKE,FD,REQUEUE,CMP_REQUEUE
+//zz ARG4 - struct timespec *utime WAIT:time* REQUEUE,CMP_REQUEUE:val2
+//zz ARG5 - u32 *uaddr2 REQUEUE,CMP_REQUEUE
+//zz ARG6 - int val3 CMP_REQUEUE
+//zz */
+//zz PRINT("sys_futex ( %p, %d, %d, %p, %p )", ARG1,ARG2,ARG3,ARG4,ARG5);
+//zz PRE_REG_READ6(long, "futex",
+//zz vki_u32 *, futex, int, op, int, val,
+//zz struct timespec *, utime, vki_u32 *, uaddr2, int, val3);
+//zz
+//zz PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
+//zz
+//zz switch(ARG2) {
+//zz case VKI_FUTEX_WAIT:
+//zz if (ARG4 != 0)
+//zz PRE_MEM_READ( "futex(timeout)", ARG4, sizeof(struct vki_timespec) );
+//zz break;
+//zz
+//zz case VKI_FUTEX_REQUEUE:
+//zz case VKI_FUTEX_CMP_REQUEUE:
+//zz PRE_MEM_READ( "futex(futex2)", ARG5, sizeof(Int) );
+//zz break;
+//zz
+//zz case VKI_FUTEX_WAKE:
+//zz case VKI_FUTEX_FD:
+//zz /* no additional pointers */
+//zz break;
+//zz
+//zz default:
+//zz SET_RESULT(-VKI_ENOSYS); // some futex function we don't understand
+//zz break;
+//zz }
+//zz }
+//zz
+//zz POST(sys_futex)
+//zz {
+//zz POST_MEM_WRITE( ARG1, sizeof(int) );
+//zz if (ARG2 == VKI_FUTEX_FD) {
+//zz if (!VG_(fd_allowed)(RES, "futex", tid, True)) {
+//zz VG_(close)(RES);
+//zz SET_RESULT( -VKI_EMFILE );
+//zz } else {
+//zz if (VG_(clo_track_fds))
+//zz VG_(record_fd_open)(tid, RES, VG_(arena_strdup)(VG_AR_CORE, (Char*)ARG1));
+//zz }
+//zz }
+//zz }
+//zz
+//zz PRE(sys_epoll_create, 0)
+//zz {
+//zz PRINT("sys_epoll_create ( %d )", ARG1);
+//zz PRE_REG_READ1(long, "epoll_create", int, size);
+//zz }
+//zz
+//zz POST(sys_epoll_create)
+//zz {
+//zz if (!VG_(fd_allowed)(RES, "epoll_create", tid, True)) {
+//zz VG_(close)(RES);
+//zz SET_RESULT( -VKI_EMFILE );
+//zz } else {
+//zz if (VG_(clo_track_fds))
+//zz VG_(record_fd_open) (tid, RES, NULL);
+//zz }
+//zz }
+//zz
+//zz PRE(sys_epoll_ctl, 0)
+//zz {
+//zz static const char* epoll_ctl_s[3] = {
+//zz "EPOLL_CTL_ADD",
+//zz "EPOLL_CTL_DEL",
+//zz "EPOLL_CTL_MOD"
+//zz };
+//zz PRINT("sys_epoll_ctl ( %d, %s, %d, %p )",
+//zz ARG1, ( ARG2<3 ? epoll_ctl_s[ARG2] : "?" ), ARG3, ARG4);
+//zz PRE_REG_READ4(long, "epoll_ctl",
+//zz int, epfd, int, op, int, fd, struct epoll_event *, event);
+//zz PRE_MEM_READ( "epoll_ctl(event)", ARG4, sizeof(struct epoll_event) );
+//zz }
+//zz
+//zz PRE(sys_epoll_wait, MayBlock)
+//zz {
+//zz PRINT("sys_epoll_wait ( %d, %p, %d, %d )", ARG1, ARG2, ARG3, ARG4);
+//zz PRE_REG_READ4(long, "epoll_wait",
+//zz int, epfd, struct epoll_event *, events,
+//zz int, maxevents, int, timeout);
+//zz PRE_MEM_WRITE( "epoll_wait(events)", ARG2, sizeof(struct epoll_event)*ARG3);
+//zz }
+//zz
+//zz POST(sys_epoll_wait)
+//zz {
+//zz if (RES > 0)
+//zz POST_MEM_WRITE( ARG2, sizeof(struct epoll_event)*RES ) ;
+//zz }
+//zz
+//zz PRE(sys_gettid, 0)
+//zz {
+//zz PRINT("sys_gettid ()");
+//zz PRE_REG_READ0(long, "gettid");
+//zz }
+//zz
+//zz PRE(sys_tkill, Special)
+//zz {
+//zz /* int tkill(pid_t tid, int sig); */
+//zz PRINT("sys_tkill ( %d, %d )", ARG1,ARG2);
+//zz PRE_REG_READ2(long, "tkill", int, tid, int, sig);
+//zz if (!VG_(client_signal_OK)(ARG2)) {
+//zz SET_RESULT( -VKI_EINVAL );
+//zz return;
+//zz }
+//zz
+//zz /* If we're sending SIGKILL, check to see if the target is one of
+//zz our threads and handle it specially. */
+//zz if (ARG2 == VKI_SIGKILL && VG_(do_sigkill)(ARG1, -1))
+//zz SET_RESULT(0);
+//zz else
+//zz SET_RESULT(VG_(do_syscall2)(SYSNO, ARG1, ARG2));
+//zz
+//zz if (VG_(clo_trace_signals))
+//zz VG_(message)(Vg_DebugMsg, "tkill: sent signal %d to pid %d",
+//zz ARG2, ARG1);
+//zz // Check to see if this kill gave us a pending signal
+//zz XXX FIXME VG_(poll_signals)(tid);
+//zz }
+//zz
+//zz PRE(sys_tgkill, Special)
+//zz {
+//zz /* int tgkill(pid_t tgid, pid_t tid, int sig); */
+//zz PRINT("sys_tgkill ( %d, %d, %d )", ARG1,ARG2,ARG3);
+//zz PRE_REG_READ3(long, "tgkill", int, tgid, int, tid, int, sig);
+//zz if (!VG_(client_signal_OK)(ARG3)) {
+//zz SET_RESULT( -VKI_EINVAL );
+//zz return;
+//zz }
+//zz
+//zz /* If we're sending SIGKILL, check to see if the target is one of
+//zz our threads and handle it specially. */
+//zz if (ARG3 == VKI_SIGKILL && VG_(do_sigkill)(ARG2, ARG1))
+//zz SET_RESULT(0);
+//zz else
+//zz SET_RESULT(VG_(do_syscall3)(SYSNO, ARG1, ARG2, ARG3));
+//zz
+//zz if (VG_(clo_trace_signals))
+//zz VG_(message)(Vg_DebugMsg, "tgkill: sent signal %d to pid %d/%d",
+//zz ARG3, ARG1, ARG2);
+//zz // Check to see if this kill gave us a pending signal
+//zz XXX FIXME VG_(poll_signals)(tid);
+//zz }
+//zz
+//zz POST(sys_tgkill)
+//zz {
+//zz if (VG_(clo_trace_signals))
+//zz VG_(message)(Vg_DebugMsg, "tgkill: sent signal %d to pid %d/%d",
+//zz ARG3, ARG1, ARG2);
+//zz // Check to see if this kill gave us a pending signal
+//zz XXX FIXME VG_(poll_signals)(tid);
+//zz }
+//zz
+//zz PRE(sys_fadvise64, 0)
+//zz {
+//zz PRINT("sys_fadvise64 ( %d, %lld, %lu, %d )", ARG1,ARG2,ARG3);
+//zz PRE_REG_READ4(long, "fadvise64",
+//zz int, fd, vki_loff_t, offset, vki_size_t, len, int, advice)
+//zz }
+//zz
+//zz PRE(sys_fadvise64_64, 0)
+//zz {
+//zz PRINT("sys_fadvise64_64 ( %d, %lld, %lld, %d )", ARG1,ARG2,ARG3);
+//zz PRE_REG_READ4(long, "fadvise64_64",
+//zz int, fd, vki_loff_t, offset, vki_loff_t, len, int, advice)
+//zz }
+//zz
+//zz // Nb: this wrapper is "Special" because we have to pad/unpad memory around
+//zz // the syscall itself, and this allows us to control exactly the code that
+//zz // gets run while the padding is in place.
+//zz PRE(sys_io_setup, Special)
+//zz {
+//zz SizeT size;
+//zz Addr addr;
+//zz
+//zz PRINT("sys_io_setup ( %u, %p )", ARG1,ARG2);
+//zz PRE_REG_READ2(long, "io_setup",
+//zz unsigned, nr_events, vki_aio_context_t *, ctxp);
+//zz PRE_MEM_WRITE( "io_setup(ctxp)", ARG2, sizeof(vki_aio_context_t) );
+//zz
+//zz size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) +
+//zz ARG1*sizeof(struct vki_io_event));
+//zz addr = VG_(find_map_space)(0, size, True);
+//zz
+//zz if (addr == 0) {
+//zz SET_RESULT( -VKI_ENOMEM );
+//zz return;
+//zz }
+//zz
+//zz VG_(map_segment)(addr, size, VKI_PROT_READ|VKI_PROT_WRITE, SF_FIXED);
+//zz
+//zz VG_(pad_address_space)(0);
+//zz SET_RESULT( VG_(do_syscall2)(SYSNO, ARG1, ARG2) );
+//zz VG_(unpad_address_space)(0);
+//zz
+//zz if (RES == 0) {
+//zz struct vki_aio_ring *r = *(struct vki_aio_ring **)ARG2;
+//zz
+//zz vg_assert(addr == (Addr)r);
+//zz vg_assert(VG_(valid_client_addr)(addr, size, tid, "io_setup"));
+//zz
+//zz VG_TRACK( new_mem_mmap, addr, size, True, True, False );
+//zz POST_MEM_WRITE( ARG2, sizeof(vki_aio_context_t) );
+//zz }
+//zz else {
+//zz VG_(unmap_range)(addr, size);
+//zz }
+//zz }
+//zz
+//zz // Nb: This wrapper is "Special" because we need 'size' to do the unmap
+//zz // after the syscall. We must get 'size' from the aio_ring structure,
+//zz // before the syscall, while the aio_ring structure still exists. (And we
+//zz // know that we must look at the aio_ring structure because Tom inspected the
+//zz // kernel and glibc sources to see what they do, yuk.)
+//zz //
+//zz // XXX This segment can be implicitly unmapped when aio
+//zz // file-descriptors are closed...
+//zz PRE(sys_io_destroy, Special)
+//zz {
+//zz Segment *s = VG_(find_segment)(ARG1);
+//zz struct vki_aio_ring *r;
+//zz SizeT size;
+//zz
+//zz PRINT("sys_io_destroy ( %llu )", (ULong)ARG1);
+//zz PRE_REG_READ1(long, "io_destroy", vki_aio_context_t, ctx);
+//zz
+//zz // If we are going to seg fault (due to a bogus ARG1) do it as late as
+//zz // possible...
+//zz r = *(struct vki_aio_ring **)ARG1;
+//zz size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) +
+//zz r->nr*sizeof(struct vki_io_event));
+//zz
+//zz SET_RESULT( VG_(do_syscall1)(SYSNO, ARG1) );
+//zz
+//zz if (RES == 0 && s != NULL) {
+//zz VG_TRACK( die_mem_munmap, ARG1, size );
+//zz VG_(unmap_range)(ARG1, size);
+//zz }
+//zz }
+//zz
+//zz PRE(sys_io_getevents, MayBlock)
+//zz {
+//zz PRINT("sys_io_getevents ( %llu, %lld, %lld, %p, %p )",
+//zz (ULong)ARG1,(Long)ARG2,(Long)ARG3,ARG4,ARG5);
+//zz PRE_REG_READ5(long, "io_getevents",
+//zz vki_aio_context_t, ctx_id, long, min_nr, long, nr,
+//zz struct io_event *, events,
+//zz struct timespec *, timeout);
+//zz if (ARG3 > 0)
+//zz PRE_MEM_WRITE( "io_getevents(events)",
+//zz ARG4, sizeof(struct vki_io_event)*ARG3 );
+//zz if (ARG5 != 0)
+//zz PRE_MEM_READ( "io_getevents(timeout)",
+//zz ARG5, sizeof(struct vki_timespec));
+//zz }
+//zz
+//zz POST(sys_io_getevents)
+//zz {
+//zz int i;
+//zz
+//zz if (RES > 0) {
+//zz POST_MEM_WRITE( ARG4, sizeof(struct vki_io_event)*RES );
+//zz for (i = 0; i < RES; i++) {
+//zz const struct vki_io_event *vev = ((struct vki_io_event *)ARG4) + i;
+//zz const struct vki_iocb *cb = (struct vki_iocb *)(Addr)vev->obj;
+//zz
+//zz switch (cb->aio_lio_opcode) {
+//zz case VKI_IOCB_CMD_PREAD:
+//zz if (vev->result > 0)
+//zz POST_MEM_WRITE( cb->aio_buf, vev->result );
+//zz break;
+//zz
+//zz case VKI_IOCB_CMD_PWRITE:
+//zz break;
+//zz
+//zz default:
+//zz VG_(message)(Vg_DebugMsg,"Warning: unhandled io_getevents opcode: %u\n",cb->aio_lio_opcode);
+//zz break;
+//zz }
+//zz }
+//zz }
+//zz }
+//zz
+//zz PRE(sys_io_submit, 0)
+//zz {
+//zz int i;
+//zz
+//zz PRINT("sys_io_submit( %llu, %lld, %p )", (ULong)ARG1,(Long)ARG2,ARG3);
+//zz PRE_REG_READ3(long, "io_submit",
+//zz vki_aio_context_t, ctx_id, long, nr,
+//zz struct iocb **, iocbpp);
+//zz PRE_MEM_READ( "io_submit(iocbpp)", ARG3, ARG2*sizeof(struct vki_iocb *) );
+//zz if (ARG3 != 0) {
+//zz for (i = 0; i < ARG2; i++) {
+//zz struct vki_iocb *cb = ((struct vki_iocb **)ARG3)[i];
+//zz PRE_MEM_READ( "io_submit(iocb)", (Addr)cb, sizeof(struct vki_iocb) );
+//zz switch (cb->aio_lio_opcode) {
+//zz case VKI_IOCB_CMD_PREAD:
+//zz PRE_MEM_WRITE( "io_submit(PREAD)", cb->aio_buf, cb->aio_nbytes );
+//zz break;
+//zz
+//zz case VKI_IOCB_CMD_PWRITE:
+//zz PRE_MEM_READ( "io_submit(PWRITE)", cb->aio_buf, cb->aio_nbytes );
+//zz break;
+//zz
+//zz default:
+//zz VG_(message)(Vg_DebugMsg,"Warning: unhandled io_submit opcode: %u\n",
+//zz cb->aio_lio_opcode);
+//zz break;
+//zz }
+//zz }
+//zz }
+//zz }
+//zz
+//zz PRE(sys_io_cancel, 0)
+//zz {
+//zz PRINT("sys_io_cancel( %llu, %p, %p )", (ULong)ARG1,ARG2,ARG3);
+//zz PRE_REG_READ3(long, "io_cancel",
+//zz vki_aio_context_t, ctx_id, struct iocb *, iocb,
+//zz struct io_event *, result);
+//zz PRE_MEM_READ( "io_cancel(iocb)", ARG2, sizeof(struct vki_iocb) );
+//zz PRE_MEM_WRITE( "io_cancel(result)", ARG3, sizeof(struct vki_io_event) );
+//zz }
+//zz
+//zz POST(sys_io_cancel)
+//zz {
+//zz POST_MEM_WRITE( ARG3, sizeof(struct vki_io_event) );
+//zz }
+//zz
+//zz #undef PRE
+//zz #undef POST
/*--------------------------------------------------------------------*/
/*--- end ---*/
diff --git a/coregrind/m_syscalls/syscalls-main.c b/coregrind/m_syscalls/syscalls-main.c
new file mode 100644
index 000000000..f2fbb0890
--- /dev/null
+++ b/coregrind/m_syscalls/syscalls-main.c
@@ -0,0 +1,970 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Handle system calls. syscalls-main.c ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2000-2005 Julian Seward
+ jseward@acm.org
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#include "libvex_guest_offsets.h"
+#include "core.h"
+#include "pub_core_libcbase.h"
+#include "pub_core_libcassert.h"
+#include "pub_core_libcprint.h"
+#include "pub_core_stacktrace.h"
+#include "pub_core_tooliface.h"
+#include "pub_core_options.h"
+#include "pub_core_signals.h"
+#include "pub_core_syscalls.h"
+
+#include "priv_types_n_macros.h"
+#include "priv_syscalls-main.h"
+
+
+/* This is the top level of the system-call handler module. All
+ system calls are channelled through here, doing two things:
+
+ * notify the tool of the events (mem/reg reads, writes) happening
+
+ * perform the syscall, usually by passing it along to the kernel
+ unmodified.
+
+ A magical piece of assembly code, do_syscall_for_client_WRK, in
+ syscall-$PLATFORM.S does the tricky bit of passing a syscall to the
+ kernel, whilst having the simulator retain control.
+*/
+
+/* The main function is VG_(client_syscall). The simulation calls it
+ whenever a client thread wants to do a syscall. The following is a
+ sketch of what it does.
+
+ * First, it rounds up the syscall number and args (which is a
+ platform dependent activity) and puts them in a struct ("args")
+ and also a copy in "orig_args".
+
+ The pre/post wrappers refer to these structs and so no longer
+ need magic macros to access any specific registers. This struct
+ is stored in thread-specific storage.
+
+
+ * The pre-wrapper is called, passing it a pointer to struct
+ "args".
+
+
+ * The pre-wrapper examines the args and pokes the tool
+ appropriately. It may modify the args; this is why "orig_args"
+ is also stored.
+
+ The pre-wrapper may choose to 'do' the syscall itself, and
+ concludes one of three outcomes:
+
+ Success(N) -- syscall is already complete, with success;
+ result is N
+
+ Fail(N) -- syscall is already complete, with failure;
+ error code is N
+
+ HandToKernel -- (the usual case): this needs to be given to
+ the kernel to be done, using the values in
+ the possibly-modified "args" struct.
+
+ In addition, the pre-wrapper may set some flags:
+
+ MayBlock -- only applicable when outcome==HandToKernel
+
+ PostOnFail -- only applicable when outcome==HandToKernel or Fail
+
+
+ * If the pre-outcome is HandToKernel, the syscall is duly handed
+ off to the kernel (perhaps involving some thread switchery, but
+ that's not important). This reduces the possible set of outcomes
+ to either Success(N) or Fail(N).
+
+
+ * The outcome (Success(N) or Fail(N)) is written back to the guest
+ register(s). This is platform specific:
+
+ x86: Success(N) ==> eax = N
+ Fail(N) ==> eax = -N
+
+ ditto amd64
+
+ ppc32: Success(N) ==> r3 = N, CR0.SO = 0
+ Fail(N) ==> r3 = N, CR0.SO = 1
+
+ * The post wrapper is called if:
+
+ - it exists, and
+ - outcome==Success or (outcome==Fail and PostOnFail is set)
+
+ The post wrapper is passed the adulterated syscall args (struct
+ "args"), and the syscall outcome (viz, Success(N) or Fail(N)).
+
+ There are several other complications, primarily to do with
+ syscalls getting interrupted, explained in comments in the code.
+*/
+
+/* CAVEATS for writing wrappers. It is important to follow these!
+
+ The macros defined in priv_types_n_macros.h are designed to help
+ decouple the wrapper logic from the actual representation of
+ syscall args/results, since these wrappers are designed to work on
+ multiple platforms.
+
+ Sometimes a PRE wrapper will complete the syscall itself, without
+ handing it to the kernel. It will use one of SET_STATUS_Success,
+ SET_STATUS_Failure or SET_STATUS_from_SysRes to set the return
+ value. It is critical to appreciate that use of the macro does not
+ immediately cause the underlying guest state to be updated -- that
+ is done by the driver logic in this file, when the wrapper returns.
+
+ As a result, PRE wrappers of the following form will malfunction:
+
+ PRE(fooble)
+ {
+ ... do stuff ...
+ SET_STATUS_Somehow(...)
+
+ // do something that assumes guest state is up to date
+ }
+
+ In particular, direct or indirect calls to VG_(poll_signals) after
+ setting STATUS can cause the guest state to be read (in order to
+ build signal frames). Do not do this. If you want a signal poll
+ after the syscall goes through, do "*flags |= SfPollAfter" and the
+ driver logic will do it for you.
+*/
+
+
+/* ---------------------------------------------------------------------
+ Do potentially blocking syscall for the client, and mess with
+ signal masks at the same time.
+ ------------------------------------------------------------------ */
+
+/* Perform a syscall on behalf of a client thread, using a specific
+ signal mask. On completion, the signal mask is set to restore_mask
+ (which presumably blocks almost everything). If a signal happens
+ during the syscall, the handler should call
+ VG_(fixup_guest_state_after_syscall_interrupted) to adjust the
+ thread's context to do the right thing.
+
+ The _WRK function is handwritten assembly. It has some very magic
+ properties. See comments at the top of
+ VG_(fixup_guest_state_after_syscall_interrupted) below for details.
+*/
+extern
+void VGA_(do_syscall_for_client_WRK)( Int syscallno,
+ void* guest_state,
+ const vki_sigset_t *syscall_mask,
+ const vki_sigset_t *restore_mask,
+ Int nsigwords );
+
+static
+void do_syscall_for_client ( Int syscallno,
+ ThreadState* tst,
+ const vki_sigset_t* syscall_mask )
+{
+ vki_sigset_t saved;
+ VGA_(do_syscall_for_client_WRK)(
+ syscallno, &tst->arch.vex,
+ syscall_mask, &saved, _VKI_NSIG_WORDS * sizeof(UWord)
+ );
+}
+
+
+
+/* ---------------------------------------------------------------------
+ Impedance matchers and misc helpers
+ ------------------------------------------------------------------ */
+
+static
+Bool eq_SyscallArgs ( SyscallArgs* a1, SyscallArgs* a2 )
+{
+ return a1->sysno == a2->sysno
+ && a1->arg1 == a2->arg1
+ && a1->arg2 == a2->arg2
+ && a1->arg3 == a2->arg3
+ && a1->arg4 == a2->arg4
+ && a1->arg5 == a2->arg5
+ && a1->arg6 == a2->arg6;
+}
+
+static
+Bool eq_SyscallStatus ( SyscallStatus* s1, SyscallStatus* s2 )
+{
+ return s1->what == s2->what
+ && s1->val == s2->val;
+}
+
+
+/* Convert between SysRet and SyscallStatus, to the extent possible. */
+
+/* This is unused. */
+/*
+static
+SysRes convert_SyscallStatus_to_SysRes ( SyscallStatus status )
+{
+ SysRes res;
+ vg_assert(status.what == SsSuccess || status.what == SsFailure);
+ res.isError = status.what == SsFailure;
+ res.val = status.val;
+ return res;
+}
+*/
+
+static
+SyscallStatus convert_SysRes_to_SyscallStatus ( SysRes res )
+{
+ SyscallStatus status;
+ status.what = res.isError ? SsFailure : SsSuccess;
+ status.val = res.val;
+ return status;
+}
+
+
+/* Impedance matchers. These convert syscall arg or result data from
+ the platform-specific in-guest-state format to the canonical
+ formats, and back. */
+
+static
+void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs* canonical,
+ /*IN*/ VexGuestArchState* gst_vanilla )
+{
+# if defined(VGP_x86_linux)
+ VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
+ canonical->sysno = gst->guest_EAX;
+ canonical->arg1 = gst->guest_EBX;
+ canonical->arg2 = gst->guest_ECX;
+ canonical->arg3 = gst->guest_EDX;
+ canonical->arg4 = gst->guest_ESI;
+ canonical->arg5 = gst->guest_EDI;
+ canonical->arg6 = gst->guest_EBP;
+# else
+# error "getSyscallArgsFromGuestState: unknown arch"
+# endif
+}
+
+static
+void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs* canonical,
+ /*OUT*/VexGuestArchState* gst_vanilla )
+{
+# if defined(VGP_x86_linux)
+ VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
+ gst->guest_EAX = canonical->sysno;
+ gst->guest_EBX = canonical->arg1;
+ gst->guest_ECX = canonical->arg2;
+ gst->guest_EDX = canonical->arg3;
+ gst->guest_ESI = canonical->arg4;
+ gst->guest_EDI = canonical->arg5;
+ gst->guest_EBP = canonical->arg6;
+# else
+# error "putSyscallArgsIntoGuestState: unknown arch"
+# endif
+}
+
+static
+void getSyscallStatusFromGuestState ( /*OUT*/SyscallStatus* canonical,
+ /*IN*/ VexGuestArchState* gst_vanilla )
+{
+# if defined(VGP_x86_linux)
+ VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
+ Int i = (Int)gst->guest_EAX;
+ canonical->what = i >= -4095 && i <= -1 ? SsFailure : SsSuccess;
+ canonical->val = (UWord)(canonical->what==SsFailure ? -i : i);
+# else
+# error "getSyscallStatusFromGuestState: unknown arch"
+# endif
+}
+
+static
+void putSyscallStatusIntoGuestState ( /*IN*/ SyscallStatus* canonical,
+ /*OUT*/VexGuestArchState* gst_vanilla )
+{
+ vg_assert(canonical->what == SsSuccess
+ || canonical->what == SsFailure);
+# if defined(VGP_x86_linux)
+ VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
+ if (canonical->what == SsFailure) {
+ /* This isn't exactly right, in that really a Failure with res
+ not in the range 1 .. 4095 is unrepresentable in the
+ Linux-x86 scheme. Oh well. */
+ gst->guest_EAX = - (Int)canonical->val;
+ } else {
+ gst->guest_EAX = canonical->val;
+ }
+# else
+# error "putSyscallStatusIntoGuestState: unknown arch"
+# endif
+}
+
+
+/* Tell me the offsets in the guest state of the syscall params, so
+ that the scalar argument checkers don't have to have this info
+ hardwired. */
+
+static
+void getSyscallArgLayout ( /*OUT*/SyscallArgLayout* layout )
+{
+# if defined(VGP_x86_linux)
+ layout->o_sysno = OFFSET_x86_EAX;
+ layout->o_arg1 = OFFSET_x86_EBX;
+ layout->o_arg2 = OFFSET_x86_ECX;
+ layout->o_arg3 = OFFSET_x86_EDX;
+ layout->o_arg4 = OFFSET_x86_ESI;
+ layout->o_arg5 = OFFSET_x86_EDI;
+ layout->o_arg6 = OFFSET_x86_EBP;
+ layout->o_retval = OFFSET_x86_EAX;
+# else
+# error "getSyscallLayout: unknown arch"
+# endif
+}
+
+
+/* ---------------------------------------------------------------------
+ The main driver logic
+ ------------------------------------------------------------------ */
+
+/* Finding the handlers for a given syscall, or faking up one
+ when no handler is found. */
+
+static
+void bad_before ( ThreadId tid,
+ SyscallArgLayout* layout,
+ /*MOD*/SyscallArgs* args,
+ /*OUT*/SyscallStatus* status,
+ /*OUT*/UWord* flags )
+{
+ VG_(message)
+ (Vg_DebugMsg,"WARNING: unhandled syscall: %llu", (ULong)args->sysno);
+ if (VG_(clo_verbosity) > 1) {
+ VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
+ }
+ VG_(message)
+ (Vg_DebugMsg,"You may be able to write your own handler.");
+ VG_(message)
+ (Vg_DebugMsg,"Read the file README_MISSING_SYSCALL_OR_IOCTL.");
+
+ SET_STATUS_Failure(VKI_ENOSYS);
+}
+
+static SyscallTableEntry bad_sys =
+ { bad_before, NULL };
+
+static const SyscallTableEntry* get_syscall_entry ( UInt syscallno )
+{
+ const SyscallTableEntry* sys = &bad_sys;
+
+ if (syscallno < VGP_(syscall_table_size) &&
+ VGP_(syscall_table)[syscallno].before != NULL)
+ sys = &VGP_(syscall_table)[syscallno];
+
+ return sys;
+}
+
+
+/* Add and remove signals from mask so that we end up telling the
+ kernel the state we actually want rather than what the client
+ wants. */
+static void sanitize_client_sigmask(ThreadId tid, vki_sigset_t *mask)
+{
+ VG_(sigdelset)(mask, VKI_SIGKILL);
+ VG_(sigdelset)(mask, VKI_SIGSTOP);
+ VG_(sigdelset)(mask, VKI_SIGVGKILL); /* never block */
+}
+
+typedef
+ struct {
+ SyscallArgs orig_args;
+ SyscallArgs args;
+ SyscallStatus status;
+ UWord flags;
+ }
+ SyscallInfo;
+
+SyscallInfo syscallInfo[VG_N_THREADS];
+
+
+/* The scheduler needs to be able to zero out these records after a
+ fork, hence this is exported from m_syscalls. */
+void VG_(clear_syscallInfo) ( Int tid )
+{
+ vg_assert(tid >= 0 && tid < VG_N_THREADS);
+ VG_(memset)( & syscallInfo[tid], 0, sizeof( syscallInfo[tid] ));
+ syscallInfo[tid].status.what = SsIdle;
+}
+
+static void ensure_initialised ( void )
+{
+ Int i;
+ static Bool init_done = False;
+ if (init_done)
+ return;
+ init_done = True;
+ for (i = 0; i < VG_N_THREADS; i++) {
+ VG_(clear_syscallInfo)( i );
+ }
+}
+
+/* --- This is the main function of this file. --- */
+
+void VG_(client_syscall) ( ThreadId tid )
+{
+ UWord sysno;
+ ThreadState* tst;
+ const SyscallTableEntry* ent;
+ SyscallArgLayout layout;
+ SyscallInfo* sci;
+
+ ensure_initialised();
+
+ vg_assert(VG_(is_valid_tid)(tid));
+ vg_assert(tid >= 1 && tid < VG_N_THREADS);
+ vg_assert(VG_(is_running_thread)(tid));
+
+ tst = VG_(get_ThreadState)(tid);
+
+ /* First off, get the syscall args and number. This is a
+ platform-dependent action. */
+
+ sci = & syscallInfo[tid];
+ vg_assert(sci->status.what == SsIdle);
+
+ getSyscallArgsFromGuestState( &sci->orig_args, &tst->arch.vex );
+
+ /* Copy .orig_args to .args. The pre-handler may modify .args, but
+ we want to keep the originals too, just in case. */
+ sci->args = sci->orig_args;
+
+ /* Save the syscall number in the thread state in case the syscall
+ is interrupted by a signal. */
+ sysno = sci->orig_args.sysno;
+
+ /* The default what-to-do-next thing is hand the syscall to the
+ kernel, so we pre-set that here. */
+ sci->status.what = SsHandToKernel;
+ sci->status.val = 0;
+ sci->flags = 0;
+
+ /* Fetch the syscall's handlers. If no handlers exist for this
+ syscall, we are given dummy handlers which force an immediate
+ return with ENOSYS. */
+ ent = get_syscall_entry(sysno);
+
+ /* Fetch the layout information, which tells us where in the guest
+ state the syscall args reside. This is a platform-dependent
+ action. This info is needed so that the scalar syscall argument
+ checks (PRE_REG_READ calls) know which bits of the guest state
+ they need to inspect. */
+ getSyscallArgLayout( &layout );
+
+ /* Make sure the tmp signal mask matches the real signal mask;
+ sigsuspend may change this. */
+ vg_assert(VG_(iseqsigset)(&tst->sig_mask, &tst->tmp_sig_mask));
+
+ /* Right, we're finally ready to Party. Call the pre-handler and
+ see what we get back. At this point:
+
+ sci->status.what is Unset (we don't know yet).
+ sci->orig_args contains the original args.
+ sci->args is the same as sci->orig_args.
+ sci->flags is zero.
+ */
+
+ PRINT("SYSCALL[%d,%d](%3lld) ", VG_(getpid)(), tid, (ULong)sysno);
+
+ /* Do any pre-syscall actions */
+ if (VG_(needs).syscall_wrapper) {
+ VG_TDICT_CALL(tool_pre_syscall, tid, sysno);
+ }
+
+ vg_assert(ent);
+ vg_assert(ent->before);
+ (ent->before)( tid,
+ &layout,
+ &sci->args, &sci->status, &sci->flags );
+
+ /* The pre-handler may have modified:
+ sci->args
+ sci->status
+ sci->flags
+ All else remains unchanged.
+ Although the args may be modified, pre handlers are not allowed
+ to change the syscall number.
+ */
+ /* Now we proceed according to what the pre-handler decided. */
+ vg_assert(sci->status.what == SsHandToKernel
+ || sci->status.what == SsSuccess
+ || sci->status.what == SsFailure);
+ vg_assert(sci->args.sysno == sci->orig_args.sysno);
+
+ if (sci->status.what == SsSuccess) {
+ /* The pre-handler completed the syscall itself, declaring
+ success. */
+ PRINT(" --> [pre-success] Success(0x%llx)\n", (Long)sci->status.val );
+
+ /* In this case thes allowable flag are to ask for a signal-poll
+ and/or a yield after the call. Changing the args isn't
+ allowed. */
+ vg_assert(0 == (sci->flags & ~(SfPollAfter | SfYieldAfter)));
+ vg_assert(eq_SyscallArgs(&sci->args, &sci->orig_args));
+ }
+
+ else
+ if (sci->status.what == SsFailure) {
+ /* The pre-handler decided to fail syscall itself. */
+ PRINT(" --> [pre-fail] Failure(0x%llx)\n", (Long)sci->status.val );
+ /* In this case, the pre-handler is also allowed to ask for the
+ post-handler to be run anyway. Changing the args is not
+ allowed. */
+ vg_assert(0 == (sci->flags & ~(SfMayBlock | SfPostOnFail | SfPollAfter)));
+ vg_assert(eq_SyscallArgs(&sci->args, &sci->orig_args));
+ }
+
+ else
+ if (sci->status.what != SsHandToKernel) {
+ /* huh?! */
+ vg_assert(0);
+ }
+
+ else /* (sci->status.what == HandToKernel) */ {
+ /* Ok, this is the usual case -- and the complicated one. There
+ are two subcases: sync and async. async is the general case
+ and is to be used when there is any possibility that the
+ syscall might block [a fact that the pre-handler must tell us
+ via the sci->flags field.] Because the tidying-away /
+ context-switch overhead of the async case could be large, if
+ we are sure that the syscall will not block, we fast-track it
+ by doing it directly in this thread, which is a lot
+ simpler. */
+
+ /* Check that the given flags are allowable: MayBlock and
+ PostOnFail are ok. */
+ vg_assert(0 == (sci->flags & ~(SfMayBlock | SfPostOnFail)));
+
+ if (sci->flags & SfMayBlock) {
+
+ /* Syscall may block, so run it asynchronously */
+ vki_sigset_t mask;
+
+// vg_assert(!(sci->flags & PadAddr));
+ PRINT(" --> [async] ... \n");
+
+ mask = tst->sig_mask;
+ sanitize_client_sigmask(tid, &mask);
+
+ /* Gack. More impedance matching. Copy the possibly
+ modified syscall args back into the guest state. */
+ vg_assert(eq_SyscallArgs(&sci->args, &sci->orig_args));
+ putSyscallArgsIntoGuestState( &sci->args, &tst->arch.vex );
+
+ /* Drop the lock */
+ VG_(set_sleeping)(tid, VgTs_WaitSys);
+
+ /* Do the call, which operates directly on the guest state,
+ not on our abstracted copies of the args/result. */
+ do_syscall_for_client(sysno, tst, &mask);
+
+ /* do_syscall_for_client may not return if the syscall was
+ interrupted by a signal. In that case, flow of control is
+ first to m_signals.async_sighandler, which calls
+ VG_(fixup_guest_state_after_syscall_interrupted), which
+ fixes up the guest state, and possibly calls
+ VG_(post_syscall). Once that's done, control drops back
+ to the scheduler. */
+
+ /* Reacquire the lock */
+ VG_(set_running)(tid);
+
+ /* Even more impedance matching. Extract the syscall status
+ from the guest state. */
+ getSyscallStatusFromGuestState( &sci->status, &tst->arch.vex );
+
+ PRINT("SYSCALL[%d,%d](%3d) ... [async] --> %s(0x%llx)\n",
+ VG_(getpid)(), tid, sysno,
+ sci->status.what==SsSuccess ? "Success" : "Failure",
+ (Long)sci->status.val );
+
+ } else {
+
+ /* run the syscall directly */
+ /* The pre-handler may have modified the syscall args, but
+ since we're passing values in ->args directly to the
+ kernel, there's no point in flushing them back to the
+ guest state. Indeed doing so could be construed as
+ incorrect. */
+
+// if (sci->flags & PadAddr)
+// VG_(pad_address_space)(VG_(client_end));
+
+ SysRes sres
+ = VG_(do_syscall6)(sysno, sci->args.arg1, sci->args.arg2,
+ sci->args.arg3, sci->args.arg4,
+ sci->args.arg5, sci->args.arg6 );
+ sci->status = convert_SysRes_to_SyscallStatus(sres);
+
+ PRINT("[sync] --> %s(0x%llx)\n",
+ sci->status.what==SsSuccess ? "Success" : "Failure",
+ (Long)sci->status.val );
+ }
+ }
+
+ vg_assert(sci->status.what == SsFailure
+ || sci->status.what == SsSuccess);
+
+ vg_assert(VG_(is_running_thread)(tid));
+
+ /* Dump the syscall result back in the guest state. This is
+ a platform-specific action. */
+ putSyscallStatusIntoGuestState( &sci->status, &tst->arch.vex );
+
+ /* Situation now:
+ - the guest state is now correctly modified following the syscall
+ - modified args, original args and syscall status are still
+ available in the syscallInfo[] entry for this syscall.
+
+ Now go on to do the post-syscall actions (read on down ..)
+ */
+ VG_(post_syscall)(tid);
+}
+
+
+/* Perform post syscall actions. The expected state on entry is
+ precisely as at the end of VG_(client_syscall), that is:
+
+ - guest state up to date following the syscall
+ - modified args, original args and syscall status are still
+ available in the syscallInfo[] entry for this syscall.
+ - syscall status matches what's in the guest state.
+
+ There are two ways to get here: the normal way -- being called by
+ VG_(client_syscall), and the unusual way, from
+ VG_(fixup_guest_state_after_syscall_interrupted).
+*/
+void VG_(post_syscall) (ThreadId tid)
+{
+ SyscallArgLayout layout;
+ SyscallInfo* sci;
+ const SyscallTableEntry* ent;
+ SyscallStatus test_status;
+ ThreadState* tst;
+ UWord sysno;
+
+ /* Preliminaries */
+ vg_assert(VG_(is_valid_tid)(tid));
+ vg_assert(tid >= 1 && tid < VG_N_THREADS);
+ vg_assert(VG_(is_running_thread)(tid));
+
+ tst = VG_(get_ThreadState)(tid);
+ sci = & syscallInfo[tid];
+
+ /* m_signals.sigvgkill_handler might call here even when not in
+ a syscall. */
+ if (sci->status.what == SsIdle || sci->status.what == SsHandToKernel) {
+ sci->status.what = SsIdle;
+ return;
+ }
+
+ /* Validate current syscallInfo entry. In particular we require
+ that the current .status matches what's actually in the guest
+ state. */
+ vg_assert(sci->status.what == SsFailure
+ || sci->status.what == SsSuccess);
+
+ getSyscallStatusFromGuestState( &test_status, &tst->arch.vex );
+ vg_assert(eq_SyscallStatus( &sci->status, &test_status ));
+ /* Ok, looks sane */
+
+ /* Get the system call number. Because the pre-handler isn't
+ allowed to mess with it, it should be the same for both the
+ original and potentially-modified args. */
+ vg_assert(sci->args.sysno == sci->orig_args.sysno);
+ sysno = sci->args.sysno;
+ ent = get_syscall_entry(sysno);
+
+ /* We need the arg layout .. sigh */
+ getSyscallArgLayout( &layout );
+
+ /* Tell the tool that the assignment has occurred, so it can update
+ shadow regs as necessary. */
+ VG_TRACK( post_reg_write, Vg_CoreSysCall, tid, layout.o_retval,
+ sizeof(UWord) );
+
+ /* Consider, either success or failure. Now run the post handler if:
+ - it exists, and
+ - status==Success or (status==Fail and PostOnFail is set)
+ */
+ if (ent->after
+ && (sci->status.what == SsSuccess
+ || (sci->status.what == SsFailure
+ && (sci->flags & SfPostOnFail) ))) {
+
+ (ent->after)( tid, &sci->args, &sci->status );
+ }
+
+ /* Because the post handler might have changed the status (eg, the
+ post-handler for sys_open can change the result from success to
+ failure if the kernel supplied a fd that it doesn't like), once
+ again dump the syscall result back in the guest state.*/
+ putSyscallStatusIntoGuestState( &sci->status, &tst->arch.vex );
+
+ /* Do any post-syscall actions required by the tool. */
+ if (VG_(needs).syscall_wrapper) {
+ SysRes res;
+ res.val = sci->status.val;
+ res.isError = sci->status.what == SsFailure;
+ VG_TDICT_CALL(tool_post_syscall, tid, sysno, res);
+ }
+
+//zz if (flags & PadAddr) {
+//zz vg_assert(!mayBlock);
+//zz VG_(unpad_address_space)(VG_(client_end));
+//zz //VG_(sanity_check_memory)();
+//zz }
+//zz
+
+ /* The syscall is done. */
+ sci->status.what = SsIdle;
+
+ /* The pre/post wrappers may have concluded that pending signals
+ might have been created, and will have set SfPollAfter to
+ request a poll for them once the syscall is done. */
+ if (sci->flags & SfPollAfter)
+ VG_(poll_signals)(tid);
+
+ /* Similarly, the wrappers might have asked for a yield
+ afterwards. */
+ if (sci->flags & SfYieldAfter)
+ VG_(vg_yield)();
+}
+
+
+/* ---------------------------------------------------------------------
+ Dealing with syscalls which get interrupted by a signal:
+ VG_(fixup_guest_state_after_syscall_interrupted)
+ ------------------------------------------------------------------ */
+
+/* Syscalls done on behalf of the client are finally handed off to the
+ kernel in VG_(client_syscall) above, either by calling
+ do_syscall_for_client (the async case), or by calling
+ VG_(do_syscall6) (the sync case).
+
+ If the syscall is not interrupted by a signal (it may block and
+ later unblock, but that's irrelevant here) then those functions
+ eventually return and so control is passed to VG_(post_syscall).
+ NB: not sure if the sync case can actually get interrupted, as it
+ operates with all signals masked.
+
+ However, the syscall may get interrupted by an async-signal. In
+ that case do_syscall_for_client/VG_(do_syscall6) do not
+ return. Instead we wind up in m_signals.async_sighandler. We need
+ to fix up the guest state to make it look like the syscall was
+ interrupted for guest. So async_sighandler calls here, and this
+ does the fixup. Note that from here we wind up calling
+ VG_(post_syscall) too.
+*/
+
+
+/* These are addresses within VGA_(_do_syscall_for_client). See syscall.S for
+ details. */
+extern const Addr VGA_(blksys_setup);
+extern const Addr VGA_(blksys_restart);
+extern const Addr VGA_(blksys_complete);
+extern const Addr VGA_(blksys_committed);
+extern const Addr VGA_(blksys_finished);
+
+
+/* Back up guest state to restart a system call. */
+
+void VG_(fixup_guest_state_to_restart_syscall) ( ThreadArchState* arch )
+{
+# if defined(VGP_x86_linux)
+ arch->vex.guest_EIP -= 2; // sizeof(int $0x80)
+
+ /* Make sure our caller is actually sane, and we're really backing
+ back over a syscall.
+
+ int $0x80 == CD 80
+ */
+ {
+ UChar *p = (UChar *)arch->vex.guest_EIP;
+
+ if (p[0] != 0xcd || p[1] != 0x80)
+ VG_(message)(Vg_DebugMsg,
+ "?! restarting over syscall at %p %02x %02x\n",
+ arch->vex.guest_EIP, p[0], p[1]);
+
+ vg_assert(p[0] == 0xcd && p[1] == 0x80);
+ }
+# else
+
+# error "VG_(fixup_guest_state_to_restart_syscall): unknown plat"
+# endif
+}
+
+/*
+ Fix up the guest state when a syscall is interrupted by a signal
+ and so has been forced to return 'sysret'.
+
+ To do this, we determine the precise state of the syscall by
+ looking at the (real) IP at the time the signal happened. The
+ syscall sequence looks like:
+
+ 1. unblock signals
+ 2. perform syscall
+ 3. save result to guest state (EAX, RAX, R3+CR0.SO)
+ 4. re-block signals
+
+ If a signal
+ happens at Then Why?
+ [1-2) restart nothing has happened (restart syscall)
+ [2] restart syscall hasn't started, or kernel wants to restart
+ [2-3) save syscall complete, but results not saved
+ [3-4) syscall complete, results saved
+
+ Sometimes we never want to restart an interrupted syscall (because
+ sigaction says not to), so we only restart if "restart" is True.
+
+ This will also call VG_(post_syscall) if the syscall has actually
+ completed (either because it was interrupted, or because it
+ actually finished). It will not call VG_(post_syscall) if the
+ syscall is set up for restart, which means that the pre-wrapper may
+ get called multiple times.
+*/
+
+void
+VG_(fixup_guest_state_after_syscall_interrupted)( ThreadId tid,
+ Addr ip,
+ UWord sysnum,
+ SysRes sysret,
+ Bool restart)
+{
+ /* Note that the sysnum arg seems to contain not-dependable-on info
+ (I think it depends on the state the real syscall was in at
+ interrupt) and so is ignored, apart from in the following
+ printf. */
+
+ static const Bool debug = False;
+
+ ThreadState* tst;
+ SyscallStatus canonical;
+ ThreadArchState* th_regs;
+ SyscallInfo* sci;
+
+ if (debug)
+ VG_(printf)( "interrupted_syscall %d: tid=%d, IP=0x%llx, "
+ "restart=%s, sysret.isError=%s, sysret.val=%lld\n",
+ (Int)sysnum,
+ (Int)tid,
+ (ULong)ip,
+ restart ? "True" : "False",
+ sysret.isError ? "True" : "False",
+ (Long)(Word)sysret.val );
+
+ vg_assert(VG_(is_valid_tid)(tid));
+ vg_assert(tid >= 1 && tid < VG_N_THREADS);
+ vg_assert(VG_(is_running_thread)(tid));
+
+ tst = VG_(get_ThreadState)(tid);
+ th_regs = &tst->arch;
+ sci = & syscallInfo[tid];
+
+ /* Figure out what the state of the syscall was by examining the
+ (real) IP at the time of the signal, and act accordingly. */
+
+ if (ip < VGA_(blksys_setup) || ip >= VGA_(blksys_finished)) {
+ VG_(printf)(" not in syscall (%p - %p)\n",
+ VGA_(blksys_setup), VGA_(blksys_finished));
+ /* Looks like we weren't in a syscall at all. Hmm. */
+ vg_assert(sci->status.what != SsIdle);
+ return;
+ }
+
+ /* We should not be here unless this thread had first started up
+ the machinery for a syscall by calling VG_(client_syscall).
+ Hence: */
+ vg_assert(sci->status.what != SsIdle);
+
+ if (ip >= VGA_(blksys_setup) && ip < VGA_(blksys_restart)) {
+ /* syscall hasn't even started; go around again */
+ if (debug)
+ VG_(printf)(" not started: restart\n");
+ vg_assert(sci->status.what == SsHandToKernel);
+ VG_(fixup_guest_state_to_restart_syscall)(th_regs);
+ }
+
+ else
+ if (ip == VGA_(blksys_restart)) {
+ /* We're either about to run the syscall, or it was interrupted
+ and the kernel restarted it. Restart if asked, otherwise
+ EINTR it. */
+ if (restart)
+ VG_(fixup_guest_state_to_restart_syscall)(th_regs);
+ else {
+ canonical = convert_SysRes_to_SyscallStatus(
+ VG_(mk_SysRes_Error)( VKI_EINTR )
+ );
+ putSyscallStatusIntoGuestState( &canonical, &th_regs->vex );
+ sci->status = canonical;
+ VG_(post_syscall)(tid);
+ }
+ }
+
+ else
+ if (ip >= VGA_(blksys_complete) && ip < VGA_(blksys_committed)) {
+ /* Syscall complete, but result hasn't been written back yet.
+ Write the SysRes we were supplied with back to the guest
+ state. */
+ if (debug)
+ VG_(printf)(" completed\n", sysret);
+ canonical = convert_SysRes_to_SyscallStatus( sysret );
+ putSyscallStatusIntoGuestState( &canonical, &th_regs->vex );
+ sci->status = canonical;
+ VG_(post_syscall)(tid);
+ }
+
+ else
+ if (ip >= VGA_(blksys_committed) && ip < VGA_(blksys_finished)) {
+ /* Result committed, but the signal mask has not been restored;
+ we expect our caller (the signal handler) will have fixed
+ this up. */
+ if (debug)
+ VG_(printf)(" all done\n");
+ VG_(post_syscall)(tid);
+ }
+
+ else
+ VG_(core_panic)("?? strange syscall interrupt state?");
+
+ /* In all cases, the syscall is now finished (even if we called
+ VG_(fixup_guest_state_to_restart_syscall), since that just
+ re-positions the guest's IP for another go at it). So we need
+ to record that fact. */
+ sci->status.what = SsIdle;
+}
+
+
+/*--------------------------------------------------------------------*/
+/*--- end syscalls-main.c ---*/
+/*--------------------------------------------------------------------*/
diff --git a/coregrind/m_syscalls/syscalls-x86-linux.c b/coregrind/m_syscalls/syscalls-x86-linux.c
index 691be0278..74f9bb135 100644
--- a/coregrind/m_syscalls/syscalls-x86-linux.c
+++ b/coregrind/m_syscalls/syscalls-x86-linux.c
@@ -37,12 +37,21 @@
#include "ume.h" /* for jmp_with_stack */
#include "pub_core_debuglog.h"
#include "pub_core_aspacemgr.h"
+#include "pub_core_options.h"
+#include "pub_core_libcbase.h"
#include "pub_core_libcassert.h"
#include "pub_core_libcprint.h"
#include "pub_core_sigframe.h"
#include "pub_core_syscalls.h"
#include "pub_core_tooliface.h"
-#include "priv_syscalls.h"
+#include "pub_core_signals.h"
+
+#include "priv_types_n_macros.h"
+#include "priv_syscalls-generic.h" /* for decls of generic wrappers */
+#include "priv_syscalls-linux.h" /* for decls of linux-ish wrappers */
+#include "priv_syscalls-main.h"
+
+#include "vki_unistd.h" /* for the __NR_* constants */
/* ---------------------------------------------------------------------
@@ -50,137 +59,6 @@
Note. Why is this stuff here?
------------------------------------------------------------------ */
-
-/* These are addresses within VGA_(client_syscall). See syscall.S for details. */
-extern const Addr VGA_(blksys_setup);
-extern const Addr VGA_(blksys_restart);
-extern const Addr VGA_(blksys_complete);
-extern const Addr VGA_(blksys_committed);
-extern const Addr VGA_(blksys_finished);
-
-// Back up to restart a system call.
-static void restart_syscall(ThreadArchState *arch)
-{
- arch->vex.guest_EIP -= 2; // sizeof(int $0x80)
-
- /* Make sure our caller is actually sane, and we're really backing
- back over a syscall.
-
- int $0x80 == CD 80
- */
- {
- UChar *p = (UChar *)arch->vex.guest_EIP;
-
- if (p[0] != 0xcd || p[1] != 0x80)
- VG_(message)(Vg_DebugMsg,
- "?! restarting over syscall at %p %02x %02x\n",
- arch->vex.guest_EIP, p[0], p[1]);
-
- vg_assert(p[0] == 0xcd && p[1] == 0x80);
- }
-}
-
-/*
- Fix up the VCPU state when a syscall is interrupted by a signal.
-
- To do this, we determine the precise state of the syscall by
- looking at the (real) eip at the time the signal happened. The
- syscall sequence looks like:
-
- 1. unblock signals
- 2. perform syscall
- 3. save result to EAX
- 4. re-block signals
-
- If a signal
- happens at Then Why?
- [1-2) restart nothing has happened (restart syscall)
- [2] restart syscall hasn't started, or kernel wants to restart
- [2-3) save syscall complete, but results not saved
- [3-4) syscall complete, results saved
-
- Sometimes we never want to restart an interrupted syscall (because
- sigaction says not to), so we only restart if "restart" is True.
-
- This will also call VG_(post_syscall)() if the syscall has actually
- completed (either because it was interrupted, or because it
- actually finished). It will not call VG_(post_syscall)() if the
- syscall is set up for restart, which means that the pre-wrapper may
- get called multiple times.
- */
-/* NB: this is identical to the amd64 version */
-void VGP_(interrupted_syscall)(ThreadId tid,
- Word eip, UWord sysnum, UWord sysret,
- Bool restart)
-{
- static const Bool debug = 0;
-
- ThreadState *tst = VG_(get_ThreadState)(tid);
- ThreadArchState *th_regs = &tst->arch;
-
- if (debug)
- VG_(printf)("interrupted_syscall: eip=%p; restart=%d eax=%d\n",
- eip, restart, sysnum);
-
- if (eip < VGA_(blksys_setup) || eip >= VGA_(blksys_finished)) {
- VG_(printf)(" not in syscall (%p - %p)\n", VGA_(blksys_setup), VGA_(blksys_finished));
- vg_assert(tst->syscallno == -1);
- return;
- }
-
- vg_assert(tst->syscallno != -1);
-
- if (eip >= VGA_(blksys_setup) && eip < VGA_(blksys_restart)) {
- /* syscall hasn't even started; go around again */
- if (debug)
- VG_(printf)(" not started: restart\n");
- restart_syscall(th_regs);
- } else if (eip == VGA_(blksys_restart)) {
- /* We're either about to run the syscall, or it was interrupted
- and the kernel restarted it. Restart if asked, otherwise
- EINTR it. */
- if (restart)
- restart_syscall(th_regs);
- else {
- th_regs->vex.VGP_SYSCALL_RET = -VKI_EINTR;
- VG_(post_syscall)(tid);
- }
- } else if (eip >= VGA_(blksys_complete) && eip < VGA_(blksys_committed)) {
- /* Syscall complete, but result hasn't been written back yet.
- The saved real CPU %eax has the result, which we need to move
- to EAX. */
- if (debug)
- VG_(printf)(" completed: ret=%d\n", sysret);
- th_regs->vex.VGP_SYSCALL_RET = sysret;
- VG_(post_syscall)(tid);
- } else if (eip >= VGA_(blksys_committed) && eip < VGA_(blksys_finished)) {
- /* Result committed, but the signal mask has not been restored;
- we expect our caller (the signal handler) will have fixed
- this up. */
- if (debug)
- VG_(printf)(" all done\n");
- VG_(post_syscall)(tid);
- } else
- VG_(core_panic)("?? strange syscall interrupt state?");
-
- tst->syscallno = -1;
-}
-
-extern void VGA_(_client_syscall)(Int syscallno,
- void* guest_state,
- const vki_sigset_t *syscall_mask,
- const vki_sigset_t *restore_mask,
- Int nsigwords);
-
-void VGA_(client_syscall)(Int syscallno, ThreadState *tst,
- const vki_sigset_t *syscall_mask)
-{
- vki_sigset_t saved;
- VGA_(_client_syscall)(syscallno, &tst->arch.vex,
- syscall_mask, &saved, _VKI_NSIG_WORDS * sizeof(UWord));
-}
-
-
/*
Allocate a stack for this thread.
@@ -204,11 +82,11 @@ static UWord* allocstack(ThreadId tid)
-1, 0);
if (stk != (void *)-1) {
- VG_(mprotect)(stk, VKI_PAGE_SIZE, VKI_PROT_NONE); /* guard page */
- tst->os_state.valgrind_stack_base = ((Addr)stk) + VKI_PAGE_SIZE;
- tst->os_state.valgrind_stack_szB = STACK_SIZE_W * sizeof(UWord);
+ VG_(mprotect)(stk, VKI_PAGE_SIZE, VKI_PROT_NONE); /* guard page */
+ tst->os_state.valgrind_stack_base = ((Addr)stk) + VKI_PAGE_SIZE;
+ tst->os_state.valgrind_stack_szB = STACK_SIZE_W * sizeof(UWord);
} else
- return (UWord*)-1;
+ return (UWord*)-1;
}
for (esp = (UWord*) tst->os_state.valgrind_stack_base;
@@ -361,9 +239,97 @@ static Int start_thread_NORETURN ( void* arg )
clone() handling
------------------------------------------------------------------ */
+/*
+ Perform a clone system call. clone is strange because it has
+ fork()-like return-twice semantics, so it needs special
+ handling here.
+
+ Upon entry, we have:
+
+ int (fn)(void*) in 0+FSZ(%esp)
+ void* child_stack in 4+FSZ(%esp)
+ int flags in 8+FSZ(%esp)
+ void* arg in 12+FSZ(%esp)
+ pid_t* child_tid in 16+FSZ(%esp)
+ pid_t* parent_tid in 20+FSZ(%esp)
+ void* tls_ptr in 24+FSZ(%esp)
+
+ System call requires:
+
+ int $__NR_clone in %eax
+ int flags in %ebx
+ void* child_stack in %ecx
+ pid_t* parent_tid in %edx
+ pid_t* child_tid in %edi
+ void* tls_ptr in %esi
+
+ Returns an Int encoded in the linux-x86 way, not a SysRes.
+ */
+#define STRINGIFZ(__str) #__str
+#define STRINGIFY(__str) STRINGIFZ(__str)
+#define FSZ "4+4+4" /* frame size = retaddr+ebx+edi */
+#define __NR_CLONE STRINGIFY(__NR_clone)
+#define __NR_EXIT STRINGIFY(__NR_exit)
+
+extern
+Int do_syscall_clone_x86_linux ( Int (*fn)(void *),
+ void* stack,
+ Int flags,
+ void* arg,
+ Int* child_tid,
+ Int* parent_tid,
+ vki_modify_ldt_t * );
+asm(
+"\n"
+"do_syscall_clone_x86_linux:\n"
+" push %ebx\n"
+" push %edi\n"
+
+ /* set up child stack with function and arg */
+" movl 4+"FSZ"(%esp), %ecx\n" /* syscall arg2: child stack */
+" movl 12+"FSZ"(%esp), %ebx\n" /* fn arg */
+" movl 0+"FSZ"(%esp), %eax\n" /* fn */
+" lea -8(%ecx), %ecx\n" /* make space on stack */
+" movl %ebx, 4(%ecx)\n" /* fn arg */
+" movl %eax, 0(%ecx)\n" /* fn */
+
+ /* get other args to clone */
+" movl 8+"FSZ"(%esp), %ebx\n" /* syscall arg1: flags */
+" movl 20+"FSZ"(%esp), %edx\n" /* syscall arg3: parent tid * */
+" movl 16+"FSZ"(%esp), %edi\n" /* syscall arg4: child tid * */
+" movl 24+"FSZ"(%esp), %esi\n" /* syscall arg5: tls_ptr * */
+" movl $"__NR_CLONE", %eax\n"
+" int $0x80\n" /* clone() */
+" testl %eax, %eax\n" /* child if retval == 0 */
+" jnz 1f\n"
+
+ /* CHILD - call thread function */
+" popl %eax\n"
+" call *%eax\n" /* call fn */
+
+ /* exit with result */
+" movl %eax, %ebx\n" /* arg1: return value from fn */
+" movl $"__NR_EXIT", %eax\n"
+" int $0x80\n"
+
+ /* Hm, exit returned */
+" ud2\n"
+
+"1: /* PARENT or ERROR */\n"
+" pop %edi\n"
+" pop %ebx\n"
+" ret\n"
+);
+
+#undef FSZ
+#undef __NR_CLONE
+#undef __NR_EXIT
+#undef STRINGIFY
+#undef STRINGIFZ
+
// forward declarations
static void setup_child ( ThreadArchState*, ThreadArchState*, Bool );
-static Int sys_set_thread_area ( ThreadId, vki_modify_ldt_t* );
+static SysRes sys_set_thread_area ( ThreadId, vki_modify_ldt_t* );
/*
When a client clones, we need to keep track of the new thread. This means:
@@ -375,20 +341,21 @@ static Int sys_set_thread_area ( ThreadId, vki_modify_ldt_t* );
but using the scheduler entrypoint for EIP, and a separate stack
for ESP.
*/
-static Int do_clone(ThreadId ptid,
- UInt flags, Addr esp,
- Int *parent_tidptr,
- Int *child_tidptr,
- vki_modify_ldt_t *tlsinfo)
+static SysRes do_clone ( ThreadId ptid,
+ UInt flags, Addr esp,
+ Int *parent_tidptr,
+ Int *child_tidptr,
+ vki_modify_ldt_t *tlsinfo)
{
static const Bool debug = False;
- ThreadId ctid = VG_(alloc_ThreadState)();
- ThreadState *ptst = VG_(get_ThreadState)(ptid);
- ThreadState *ctst = VG_(get_ThreadState)(ctid);
- UWord *stack;
- Segment *seg;
- Int ret;
+ ThreadId ctid = VG_(alloc_ThreadState)();
+ ThreadState* ptst = VG_(get_ThreadState)(ptid);
+ ThreadState* ctst = VG_(get_ThreadState)(ctid);
+ UWord* stack;
+ Segment* seg;
+ SysRes res;
+ Int eax;
vki_sigset_t blockall, savedmask;
VG_(sigfillset)(&blockall);
@@ -416,7 +383,9 @@ static Int do_clone(ThreadId ptid,
is passed as an arg to setup_child. */
setup_child( &ctst->arch, &ptst->arch, True /*VG_(clo_support_elan3)*/ );
- VGP_SET_SYSCALL_RESULT(ctst->arch, 0);
+ /* Make sys_clone appear to have returned zero in the child. */
+ ctst->arch.vex.guest_EAX = 0;
+
if (esp != 0)
ctst->arch.vex.guest_ESP = esp;
@@ -447,13 +416,14 @@ static Int do_clone(ThreadId ptid,
if (flags & VKI_CLONE_SETTLS) {
if (debug)
- VG_(printf)("clone child has SETTLS: tls info at %p: idx=%d base=%p limit=%x; esp=%p fs=%x gs=%x\n",
- tlsinfo, tlsinfo->entry_number, tlsinfo->base_addr, tlsinfo->limit,
+ VG_(printf)("clone child has SETTLS: tls info at %p: idx=%d "
+ "base=%p limit=%x; esp=%p fs=%x gs=%x\n",
+ tlsinfo, tlsinfo->entry_number,
+ tlsinfo->base_addr, tlsinfo->limit,
ptst->arch.vex.guest_ESP,
ctst->arch.vex.guest_FS, ctst->arch.vex.guest_GS);
- ret = sys_set_thread_area(ctid, tlsinfo);
-
- if (ret != 0)
+ res = sys_set_thread_area(ctid, tlsinfo);
+ if (res.isError)
goto out;
}
@@ -463,30 +433,37 @@ static Int do_clone(ThreadId ptid,
VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, &savedmask);
/* Create the new thread */
- ret = VG_(clone)(start_thread_NORETURN, stack, flags, &VG_(threads)[ctid],
- child_tidptr, parent_tidptr, NULL);
-
+ eax = do_syscall_clone_x86_linux(
+ start_thread_NORETURN, stack, flags, &VG_(threads)[ctid],
+ child_tidptr, parent_tidptr, NULL
+ );
+ res = VG_(mk_SysRes_x86_linux)( eax );
VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
out:
- if (ret < 0) {
+ if (res.isError) {
/* clone failed */
VGP_(cleanup_thread)(&ctst->arch);
ctst->status = VgTs_Empty;
}
- return ret;
+ return res;
}
+
/* Do a clone which is really a fork() */
-static Int do_fork_clone(ThreadId tid, UInt flags, Addr esp, Int *parent_tidptr, Int *child_tidptr)
+static SysRes do_fork_clone ( ThreadId tid,
+ UInt flags, Addr esp,
+ Int* parent_tidptr,
+ Int* child_tidptr )
{
vki_sigset_t fork_saved_mask;
vki_sigset_t mask;
- Int ret;
+ SysRes res;
- if (flags & (VKI_CLONE_SETTLS | VKI_CLONE_FS | VKI_CLONE_VM | VKI_CLONE_FILES | VKI_CLONE_VFORK))
- return -VKI_EINVAL;
+ if (flags & (VKI_CLONE_SETTLS | VKI_CLONE_FS | VKI_CLONE_VM
+ | VKI_CLONE_FILES | VKI_CLONE_VFORK))
+ return VG_(mk_SysRes_Error)( VKI_EINVAL );
/* Block all signals during fork, so that we can fix things up in
the child without being interrupted. */
@@ -497,19 +474,22 @@ static Int do_fork_clone(ThreadId tid, UInt flags, Addr esp, Int *parent_tidptr,
/* Since this is the fork() form of clone, we don't need all that
VG_(clone) stuff */
- ret = VG_(do_syscall5)(__NR_clone, flags, (UWord)NULL, (UWord)parent_tidptr,
+ res = VG_(do_syscall5)(__NR_clone, flags, (UWord)NULL, (UWord)parent_tidptr,
(UWord)NULL, (UWord)child_tidptr);
- if (ret == 0) {
+ if (!res.isError && res.val == 0) {
/* child */
VG_(do_atfork_child)(tid);
/* restore signal mask */
VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
- } else if (ret > 0) {
+ }
+ else
+ if (!res.isError && res.val > 0) {
/* parent */
if (VG_(clo_trace_syscalls))
- VG_(printf)(" clone(fork): process %d created child %d\n", VG_(getpid)(), ret);
+ VG_(printf)(" clone(fork): process %d created child %d\n",
+ VG_(getpid)(), res.val);
VG_(do_atfork_parent)(tid);
@@ -517,7 +497,7 @@ static Int do_fork_clone(ThreadId tid, UInt flags, Addr esp, Int *parent_tidptr,
VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
}
- return ret;
+ return res;
}
/* ---------------------------------------------------------------------
@@ -585,7 +565,7 @@ static Int do_fork_clone(ThreadId tid, UInt flags, Addr esp, Int *parent_tidptr,
static
void translate_to_hw_format ( /* IN */ vki_modify_ldt_t* inn,
- /* OUT */ VexGuestX86SegDescr* out,
+ /* OUT */ VexGuestX86SegDescr* out,
Int oldmode )
{
UInt entry_1, entry_2;
@@ -655,22 +635,22 @@ static void free_LDT_or_GDT ( VexGuestX86SegDescr* dt )
static void copy_LDT_from_to ( VexGuestX86SegDescr* src,
VexGuestX86SegDescr* dst )
{
- Int i;
- vg_assert(src);
- vg_assert(dst);
- for (i = 0; i < VEX_GUEST_X86_LDT_NENT; i++)
- dst[i] = src[i];
+ Int i;
+ vg_assert(src);
+ vg_assert(dst);
+ for (i = 0; i < VEX_GUEST_X86_LDT_NENT; i++)
+ dst[i] = src[i];
}
/* Copy contents between two existing GDTs. */
static void copy_GDT_from_to ( VexGuestX86SegDescr* src,
VexGuestX86SegDescr* dst )
{
- Int i;
- vg_assert(src);
- vg_assert(dst);
- for (i = 0; i < VEX_GUEST_X86_GDT_NENT; i++)
- dst[i] = src[i];
+ Int i;
+ vg_assert(src);
+ vg_assert(dst);
+ for (i = 0; i < VEX_GUEST_X86_GDT_NENT; i++)
+ dst[i] = src[i];
}
/* Free this thread's DTs, if it has any. */
@@ -709,9 +689,9 @@ static void deallocate_LGDTs_for_thread ( VexGuestX86State* vex )
* the security checks done on new descriptors.
*/
static
-Int read_ldt ( ThreadId tid, UChar* ptr, UInt bytecount )
+SysRes read_ldt ( ThreadId tid, UChar* ptr, UInt bytecount )
{
- Int err;
+ SysRes res;
UInt i, size;
UChar* ldt;
@@ -723,7 +703,7 @@ Int read_ldt ( ThreadId tid, UChar* ptr, UInt bytecount )
vg_assert(8 == sizeof(VexGuestX86SegDescr));
ldt = (Char*)(VG_(threads)[tid].arch.vex.guest_LDT);
- err = 0;
+ res = VG_(mk_SysRes_Success)( 0 );
if (ldt == NULL)
/* LDT not allocated, meaning all entries are null */
goto out;
@@ -732,19 +712,19 @@ Int read_ldt ( ThreadId tid, UChar* ptr, UInt bytecount )
if (size > bytecount)
size = bytecount;
- err = size;
+ res = VG_(mk_SysRes_Success)( size );
for (i = 0; i < size; i++)
ptr[i] = ldt[i];
out:
- return err;
+ return res;
}
static
-Int write_ldt ( ThreadId tid, void* ptr, UInt bytecount, Int oldmode )
+SysRes write_ldt ( ThreadId tid, void* ptr, UInt bytecount, Int oldmode )
{
- Int error;
+ SysRes res;
VexGuestX86SegDescr* ldt;
vki_modify_ldt_t* ldt_info;
@@ -759,11 +739,11 @@ Int write_ldt ( ThreadId tid, void* ptr, UInt bytecount, Int oldmode )
ldt = (VexGuestX86SegDescr*)VG_(threads)[tid].arch.vex.guest_LDT;
ldt_info = (vki_modify_ldt_t*)ptr;
- error = -VKI_EINVAL;
+ res = VG_(mk_SysRes_Error)( VKI_EINVAL );
if (bytecount != sizeof(vki_modify_ldt_t))
goto out;
- error = -VKI_EINVAL;
+ res = VG_(mk_SysRes_Error)( VKI_EINVAL );
if (ldt_info->entry_number >= VEX_GUEST_X86_LDT_NENT)
goto out;
if (ldt_info->contents == 3) {
@@ -782,17 +762,17 @@ Int write_ldt ( ThreadId tid, void* ptr, UInt bytecount, Int oldmode )
/* Install the new entry ... */
translate_to_hw_format ( ldt_info, &ldt[ldt_info->entry_number], oldmode );
- error = 0;
+ res = VG_(mk_SysRes_Success)( 0 );
out:
- return error;
+ return res;
}
-static Int sys_modify_ldt ( ThreadId tid,
- Int func, void* ptr, UInt bytecount )
+static SysRes sys_modify_ldt ( ThreadId tid,
+ Int func, void* ptr, UInt bytecount )
{
- Int ret = -VKI_ENOSYS;
+ SysRes ret = VG_(mk_SysRes_Error)( VKI_ENOSYS );
switch (func) {
case 0:
@@ -815,16 +795,16 @@ static Int sys_modify_ldt ( ThreadId tid,
}
-static Int sys_set_thread_area ( ThreadId tid, vki_modify_ldt_t* info )
+static SysRes sys_set_thread_area ( ThreadId tid, vki_modify_ldt_t* info )
{
- Int idx;
+ Int idx;
VexGuestX86SegDescr* gdt;
vg_assert(8 == sizeof(VexGuestX86SegDescr));
vg_assert(sizeof(HWord) == sizeof(VexGuestX86SegDescr*));
if (info == NULL)
- return -VKI_EFAULT;
+ return VG_(mk_SysRes_Error)( VKI_EFAULT );
gdt = (VexGuestX86SegDescr*)VG_(threads)[tid].arch.vex.guest_GDT;
@@ -845,9 +825,9 @@ static Int sys_set_thread_area ( ThreadId tid, vki_modify_ldt_t* info )
}
if (idx == VEX_GUEST_X86_GDT_NENT)
- return -VKI_ESRCH;
+ return VG_(mk_SysRes_Error)( VKI_ESRCH );
} else if (idx < 0 || idx >= VEX_GUEST_X86_GDT_NENT) {
- return -VKI_EINVAL;
+ return VG_(mk_SysRes_Error)( VKI_EINVAL );
}
translate_to_hw_format(info, &gdt[idx], 0);
@@ -859,49 +839,49 @@ static Int sys_set_thread_area ( ThreadId tid, vki_modify_ldt_t* info )
VG_TRACK( post_mem_write, Vg_CoreSysCall, tid,
(Addr) & info->entry_number, sizeof(unsigned int) );
- return 0;
+ return VG_(mk_SysRes_Success)( 0 );
}
-static Int sys_get_thread_area ( ThreadId tid, vki_modify_ldt_t* info )
-{
- Int idx;
- VexGuestX86SegDescr* gdt;
-
- vg_assert(sizeof(HWord) == sizeof(VexGuestX86SegDescr*));
- vg_assert(8 == sizeof(VexGuestX86SegDescr));
-
- if (info == NULL)
- return -VKI_EFAULT;
-
- idx = info->entry_number;
-
- if (idx < 0 || idx >= VEX_GUEST_X86_GDT_NENT)
- return -VKI_EINVAL;
-
- gdt = (VexGuestX86SegDescr*)VG_(threads)[tid].arch.vex.guest_GDT;
-
- /* If the thread doesn't have a GDT, allocate it now. */
- if (!gdt) {
- gdt = alloc_zeroed_x86_GDT();
- VG_(threads)[tid].arch.vex.guest_GDT = (HWord)gdt;
- }
-
- info->base_addr = ( gdt[idx].LdtEnt.Bits.BaseHi << 24 ) |
- ( gdt[idx].LdtEnt.Bits.BaseMid << 16 ) |
- gdt[idx].LdtEnt.Bits.BaseLow;
- info->limit = ( gdt[idx].LdtEnt.Bits.LimitHi << 16 ) |
- gdt[idx].LdtEnt.Bits.LimitLow;
- info->seg_32bit = gdt[idx].LdtEnt.Bits.Default_Big;
- info->contents = ( gdt[idx].LdtEnt.Bits.Type >> 2 ) & 0x3;
- info->read_exec_only = ( gdt[idx].LdtEnt.Bits.Type & 0x1 ) ^ 0x1;
- info->limit_in_pages = gdt[idx].LdtEnt.Bits.Granularity;
- info->seg_not_present = gdt[idx].LdtEnt.Bits.Pres ^ 0x1;
- info->useable = gdt[idx].LdtEnt.Bits.Sys;
- info->reserved = 0;
-
- return 0;
-}
+//zz static Int sys_get_thread_area ( ThreadId tid, vki_modify_ldt_t* info )
+//zz {
+//zz Int idx;
+//zz VexGuestX86SegDescr* gdt;
+//zz
+//zz vg_assert(sizeof(HWord) == sizeof(VexGuestX86SegDescr*));
+//zz vg_assert(8 == sizeof(VexGuestX86SegDescr));
+//zz
+//zz if (info == NULL)
+//zz return -VKI_EFAULT;
+//zz
+//zz idx = info->entry_number;
+//zz
+//zz if (idx < 0 || idx >= VEX_GUEST_X86_GDT_NENT)
+//zz return -VKI_EINVAL;
+//zz
+//zz gdt = (VexGuestX86SegDescr*)VG_(threads)[tid].arch.vex.guest_GDT;
+//zz
+//zz /* If the thread doesn't have a GDT, allocate it now. */
+//zz if (!gdt) {
+//zz gdt = alloc_zeroed_x86_GDT();
+//zz VG_(threads)[tid].arch.vex.guest_GDT = (HWord)gdt;
+//zz }
+//zz
+//zz info->base_addr = ( gdt[idx].LdtEnt.Bits.BaseHi << 24 ) |
+//zz ( gdt[idx].LdtEnt.Bits.BaseMid << 16 ) |
+//zz gdt[idx].LdtEnt.Bits.BaseLow;
+//zz info->limit = ( gdt[idx].LdtEnt.Bits.LimitHi << 16 ) |
+//zz gdt[idx].LdtEnt.Bits.LimitLow;
+//zz info->seg_32bit = gdt[idx].LdtEnt.Bits.Default_Big;
+//zz info->contents = ( gdt[idx].LdtEnt.Bits.Type >> 2 ) & 0x3;
+//zz info->read_exec_only = ( gdt[idx].LdtEnt.Bits.Type & 0x1 ) ^ 0x1;
+//zz info->limit_in_pages = gdt[idx].LdtEnt.Bits.Granularity;
+//zz info->seg_not_present = gdt[idx].LdtEnt.Bits.Pres ^ 0x1;
+//zz info->useable = gdt[idx].LdtEnt.Bits.Sys;
+//zz info->reserved = 0;
+//zz
+//zz return 0;
+//zz }
/* ---------------------------------------------------------------------
More thread stuff
@@ -946,50 +926,64 @@ static void setup_child ( /*OUT*/ ThreadArchState *child,
}
}
+
/* ---------------------------------------------------------------------
PRE/POST wrappers for x86/Linux-specific syscalls
------------------------------------------------------------------ */
-// Nb: See the comment above the generic PRE/POST wrappers in
-// coregrind/vg_syscalls.c for notes about how they work.
-
-#define PRE(name, f) PRE_TEMPLATE(static, x86_linux, name, f)
-#define POST(name) POST_TEMPLATE(static, x86_linux, name)
-
-PRE(old_select, MayBlock)
-{
- /* struct sel_arg_struct {
- unsigned long n;
- fd_set *inp, *outp, *exp;
- struct timeval *tvp;
- };
- */
- PRE_REG_READ1(long, "old_select", struct sel_arg_struct *, args);
- PRE_MEM_READ( "old_select(args)", ARG1, 5*sizeof(UWord) );
-
- {
- UInt* arg_struct = (UInt*)ARG1;
- UInt a1, a2, a3, a4, a5;
-
- a1 = arg_struct[0];
- a2 = arg_struct[1];
- a3 = arg_struct[2];
- a4 = arg_struct[3];
- a5 = arg_struct[4];
-
- PRINT("old_select ( %d, %p, %p, %p, %p )", a1,a2,a3,a4,a5);
- if (a2 != (Addr)NULL)
- PRE_MEM_READ( "old_select(readfds)", a2, a1/8 /* __FD_SETSIZE/8 */ );
- if (a3 != (Addr)NULL)
- PRE_MEM_READ( "old_select(writefds)", a3, a1/8 /* __FD_SETSIZE/8 */ );
- if (a4 != (Addr)NULL)
- PRE_MEM_READ( "old_select(exceptfds)", a4, a1/8 /* __FD_SETSIZE/8 */ );
- if (a5 != (Addr)NULL)
- PRE_MEM_READ( "old_select(timeout)", a5, sizeof(struct vki_timeval) );
- }
-}
-
-PRE(sys_clone, Special)
+#define PRE(name) DEFN_PRE_TEMPLATE(x86_linux, name)
+#define POST(name) DEFN_POST_TEMPLATE(x86_linux, name)
+
+/* Add prototypes for the wrappers declared here, so that gcc doesn't
+ harass us for not having prototypes. Really this is a kludge --
+ the right thing to do is to make these wrappers 'static' since they
+ aren't visible outside this file, but that requires even more macro
+ magic. */
+DECL_TEMPLATE(x86_linux, sys_socketcall);
+DECL_TEMPLATE(x86_linux, sys_stat64);
+DECL_TEMPLATE(x86_linux, sys_fstat64);
+DECL_TEMPLATE(x86_linux, sys_lstat64);
+DECL_TEMPLATE(x86_linux, sys_clone);
+DECL_TEMPLATE(x86_linux, old_mmap);
+DECL_TEMPLATE(x86_linux, sys_sigreturn);
+DECL_TEMPLATE(x86_linux, sys_ipc);
+DECL_TEMPLATE(x86_linux, sys_rt_sigreturn);
+DECL_TEMPLATE(x86_linux, sys_modify_ldt);
+
+//zz PRE(old_select, MayBlock)
+//zz {
+//zz /* struct sel_arg_struct {
+//zz unsigned long n;
+//zz fd_set *inp, *outp, *exp;
+//zz struct timeval *tvp;
+//zz };
+//zz */
+//zz PRE_REG_READ1(long, "old_select", struct sel_arg_struct *, args);
+//zz PRE_MEM_READ( "old_select(args)", ARG1, 5*sizeof(UWord) );
+//zz
+//zz {
+//zz UInt* arg_struct = (UInt*)ARG1;
+//zz UInt a1, a2, a3, a4, a5;
+//zz
+//zz a1 = arg_struct[0];
+//zz a2 = arg_struct[1];
+//zz a3 = arg_struct[2];
+//zz a4 = arg_struct[3];
+//zz a5 = arg_struct[4];
+//zz
+//zz PRINT("old_select ( %d, %p, %p, %p, %p )", a1,a2,a3,a4,a5);
+//zz if (a2 != (Addr)NULL)
+//zz PRE_MEM_READ( "old_select(readfds)", a2, a1/8 /* __FD_SETSIZE/8 */ );
+//zz if (a3 != (Addr)NULL)
+//zz PRE_MEM_READ( "old_select(writefds)", a3, a1/8 /* __FD_SETSIZE/8 */ );
+//zz if (a4 != (Addr)NULL)
+//zz PRE_MEM_READ( "old_select(exceptfds)", a4, a1/8 /* __FD_SETSIZE/8 */ );
+//zz if (a5 != (Addr)NULL)
+//zz PRE_MEM_READ( "old_select(timeout)", a5, sizeof(struct vki_timeval) );
+//zz }
+//zz }
+
+PRE(sys_clone)
{
UInt cloneflags;
@@ -1004,21 +998,21 @@ PRE(sys_clone, Special)
if (ARG1 & VKI_CLONE_PARENT_SETTID) {
PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
if (!VG_(is_addressable)(ARG3, sizeof(Int), VKI_PROT_WRITE)) {
- SET_RESULT( -VKI_EFAULT );
+ SET_STATUS_Failure( VKI_EFAULT );
return;
}
}
if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
PRE_MEM_WRITE("clone(child_tidptr)", ARG5, sizeof(Int));
if (!VG_(is_addressable)(ARG5, sizeof(Int), VKI_PROT_WRITE)) {
- SET_RESULT( -VKI_EFAULT );
+ SET_STATUS_Failure( VKI_EFAULT );
return;
}
}
if (ARG1 & VKI_CLONE_SETTLS) {
PRE_MEM_READ("clone(tls_user_desc)", ARG4, sizeof(vki_modify_ldt_t));
if (!VG_(is_addressable)(ARG4, sizeof(vki_modify_ldt_t), VKI_PROT_READ)) {
- SET_RESULT( -VKI_EFAULT );
+ SET_STATUS_Failure( VKI_EFAULT );
return;
}
}
@@ -1026,7 +1020,7 @@ PRE(sys_clone, Special)
cloneflags = ARG1;
if (!VG_(client_signal_OK)(ARG1 & VKI_CSIGNAL)) {
- SET_RESULT( -VKI_EINVAL );
+ SET_STATUS_Failure( VKI_EINVAL );
return;
}
@@ -1040,6 +1034,7 @@ PRE(sys_clone, Special)
if (
(cloneflags == 0x100011 || cloneflags == 0x1200011
|| cloneflags == 0x7D0F00
+ || cloneflags == 0x790F00
|| cloneflags == 0x3D0F00
|| cloneflags == 0xF00
|| cloneflags == 0xF21)) {
@@ -1051,15 +1046,17 @@ PRE(sys_clone, Special)
}
/* Only look at the flags we really care about */
- switch(cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
+ switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
+ | VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
/* thread creation */
- SET_RESULT(do_clone(tid,
- ARG1, /* flags */
- (Addr)ARG2, /* child ESP */
- (Int *)ARG3, /* parent_tidptr */
- (Int *)ARG5, /* child_tidptr */
- (vki_modify_ldt_t *)ARG4)); /* set_tls */
+ SET_STATUS_from_SysRes(
+ do_clone(tid,
+ ARG1, /* flags */
+ (Addr)ARG2, /* child ESP */
+ (Int *)ARG3, /* parent_tidptr */
+ (Int *)ARG5, /* child_tidptr */
+ (vki_modify_ldt_t *)ARG4)); /* set_tls */
break;
case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
@@ -1067,11 +1064,12 @@ PRE(sys_clone, Special)
cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM);
case 0: /* plain fork */
- SET_RESULT(do_fork_clone(tid,
- cloneflags, /* flags */
- (Addr)ARG2, /* child ESP */
- (Int *)ARG3, /* parent_tidptr */
- (Int *)ARG5)); /* child_tidptr */
+ SET_STATUS_from_SysRes(
+ do_fork_clone(tid,
+ cloneflags, /* flags */
+ (Addr)ARG2, /* child ESP */
+ (Int *)ARG3, /* parent_tidptr */
+ (Int *)ARG5)); /* child_tidptr */
break;
default:
@@ -1094,7 +1092,7 @@ PRE(sys_clone, Special)
("Valgrind does not support general clone().");
}
- if (!VG_(is_kerror)(RES)) {
+ if (SUCCESS) {
if (ARG1 & VKI_CLONE_PARENT_SETTID)
POST_MEM_WRITE(ARG3, sizeof(Int));
if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
@@ -1102,53 +1100,77 @@ PRE(sys_clone, Special)
/* Thread creation was successful; let the child have the chance
to run */
- VG_(vg_yield)();
+ *flags |= SfYieldAfter;
}
}
-PRE(sys_sigreturn, Special)
+PRE(sys_sigreturn)
{
+ ThreadState* tst;
PRINT("sigreturn ( )");
+ vg_assert(VG_(is_valid_tid)(tid));
+ vg_assert(tid >= 1 && tid < VG_N_THREADS);
+ vg_assert(VG_(is_running_thread)(tid));
+
/* Adjust esp to point to start of frame; skip back up over
sigreturn sequence's "popl %eax" and handler ret addr */
+ tst = VG_(get_ThreadState)(tid);
tst->arch.vex.guest_ESP -= sizeof(Addr)+sizeof(Word);
/* This is only so that the EIP is (might be) useful to report if
something goes wrong in the sigreturn */
- restart_syscall(&tst->arch);
+ VG_(fixup_guest_state_to_restart_syscall)(&tst->arch);
VG_(sigframe_destroy)(tid, False);
- /* Keep looking for signals until there are none */
- VG_(poll_signals)(tid);
+ /* For unclear reasons, it appears we need the syscall to return
+ without changing %EAX. Since %EAX is the return value, and can
+ denote either success or failure, we must set up so that the
+ driver logic copies it back unchanged. Also, note %EAX is of
+ the guest registers written by VG_(sigframe_destroy). */
+ SET_STATUS_from_SysRes(
+ VG_(mk_SysRes_x86_linux)( tst->arch.vex.guest_EAX )
+ );
- /* placate return-must-be-set assertion */
- SET_RESULT(RES);
+ /* Check to see if some any signals arose as a result of this. */
+ *flags |= SfPollAfter;
}
-PRE(sys_rt_sigreturn, Special)
+PRE(sys_rt_sigreturn)
{
+ ThreadState* tst;
PRINT("rt_sigreturn ( )");
+ vg_assert(VG_(is_valid_tid)(tid));
+ vg_assert(tid >= 1 && tid < VG_N_THREADS);
+ vg_assert(VG_(is_running_thread)(tid));
+
/* Adjust esp to point to start of frame; skip back up over handler
ret addr */
+ tst = VG_(get_ThreadState)(tid);
tst->arch.vex.guest_ESP -= sizeof(Addr);
/* This is only so that the EIP is (might be) useful to report if
something goes wrong in the sigreturn */
- restart_syscall(&tst->arch);
+ VG_(fixup_guest_state_to_restart_syscall)(&tst->arch);
VG_(sigframe_destroy)(tid, True);
- /* Keep looking for signals until there are none */
- VG_(poll_signals)(tid);
+ /* For unclear reasons, it appears we need the syscall to return
+ without changing %EAX. Since %EAX is the return value, and can
+ denote either success or failure, we must set up so that the
+ driver logic copies it back unchanged. Also, note %EAX is of
+ the guest registers written by VG_(sigframe_destroy). */
+ SET_STATUS_from_SysRes(
+ VG_(mk_SysRes_x86_linux)( tst->arch.vex.guest_EAX )
+ );
- /* placate return-must-be-set assertion */
- SET_RESULT(RES);
+ /* Check to see if some any signals arose as a result of this. */
+ *flags |= SfPollAfter;
}
-PRE(sys_modify_ldt, Special)
+PRE(sys_modify_ldt)
{
PRINT("sys_modify_ldt ( %d, %p, %d )", ARG1,ARG2,ARG3);
PRE_REG_READ3(int, "modify_ldt", int, func, void *, ptr,
@@ -1163,101 +1185,101 @@ PRE(sys_modify_ldt, Special)
PRE_MEM_READ( "modify_ldt(ptr)", ARG2, sizeof(vki_modify_ldt_t) );
}
/* "do" the syscall ourselves; the kernel never sees it */
- SET_RESULT( sys_modify_ldt( tid, ARG1, (void*)ARG2, ARG3 ) );
+ SET_STATUS_from_SysRes( sys_modify_ldt( tid, ARG1, (void*)ARG2, ARG3 ) );
- if (ARG1 == 0 && !VG_(is_kerror)(RES) && RES > 0) {
+ if (ARG1 == 0 && SUCCESS && RES > 0) {
POST_MEM_WRITE( ARG2, RES );
}
}
-PRE(sys_set_thread_area, Special)
-{
- PRINT("sys_set_thread_area ( %p )", ARG1);
- PRE_REG_READ1(int, "set_thread_area", struct user_desc *, u_info)
- PRE_MEM_READ( "set_thread_area(u_info)", ARG1, sizeof(vki_modify_ldt_t) );
-
- /* "do" the syscall ourselves; the kernel never sees it */
- SET_RESULT( sys_set_thread_area( tid, (void *)ARG1 ) );
-}
-
-PRE(sys_get_thread_area, Special)
-{
- PRINT("sys_get_thread_area ( %p )", ARG1);
- PRE_REG_READ1(int, "get_thread_area", struct user_desc *, u_info)
- PRE_MEM_WRITE( "get_thread_area(u_info)", ARG1, sizeof(vki_modify_ldt_t) );
-
- /* "do" the syscall ourselves; the kernel never sees it */
- SET_RESULT( sys_get_thread_area( tid, (void *)ARG1 ) );
-
- if (!VG_(is_kerror)(RES)) {
- POST_MEM_WRITE( ARG1, sizeof(vki_modify_ldt_t) );
- }
-}
-
-// Parts of this are x86-specific, but the *PEEK* cases are generic.
-// XXX: Why is the memory pointed to by ARG3 never checked?
-PRE(sys_ptrace, 0)
-{
- PRINT("sys_ptrace ( %d, %d, %p, %p )", ARG1,ARG2,ARG3,ARG4);
- PRE_REG_READ4(int, "ptrace",
- long, request, long, pid, long, addr, long, data);
- switch (ARG1) {
- case VKI_PTRACE_PEEKTEXT:
- case VKI_PTRACE_PEEKDATA:
- case VKI_PTRACE_PEEKUSR:
- PRE_MEM_WRITE( "ptrace(peek)", ARG4,
- sizeof (long));
- break;
- case VKI_PTRACE_GETREGS:
- PRE_MEM_WRITE( "ptrace(getregs)", ARG4,
- sizeof (struct vki_user_regs_struct));
- break;
- case VKI_PTRACE_GETFPREGS:
- PRE_MEM_WRITE( "ptrace(getfpregs)", ARG4,
- sizeof (struct vki_user_i387_struct));
- break;
- case VKI_PTRACE_GETFPXREGS:
- PRE_MEM_WRITE( "ptrace(getfpxregs)", ARG4,
- sizeof(struct vki_user_fxsr_struct) );
- break;
- case VKI_PTRACE_SETREGS:
- PRE_MEM_READ( "ptrace(setregs)", ARG4,
- sizeof (struct vki_user_regs_struct));
- break;
- case VKI_PTRACE_SETFPREGS:
- PRE_MEM_READ( "ptrace(setfpregs)", ARG4,
- sizeof (struct vki_user_i387_struct));
- break;
- case VKI_PTRACE_SETFPXREGS:
- PRE_MEM_READ( "ptrace(setfpxregs)", ARG4,
- sizeof(struct vki_user_fxsr_struct) );
- break;
- default:
- break;
- }
-}
-
-POST(sys_ptrace)
-{
- switch (ARG1) {
- case VKI_PTRACE_PEEKTEXT:
- case VKI_PTRACE_PEEKDATA:
- case VKI_PTRACE_PEEKUSR:
- POST_MEM_WRITE( ARG4, sizeof (long));
- break;
- case VKI_PTRACE_GETREGS:
- POST_MEM_WRITE( ARG4, sizeof (struct vki_user_regs_struct));
- break;
- case VKI_PTRACE_GETFPREGS:
- POST_MEM_WRITE( ARG4, sizeof (struct vki_user_i387_struct));
- break;
- case VKI_PTRACE_GETFPXREGS:
- POST_MEM_WRITE( ARG4, sizeof(struct vki_user_fxsr_struct) );
- break;
- default:
- break;
- }
-}
+//zz PRE(sys_set_thread_area, Special)
+//zz {
+//zz PRINT("sys_set_thread_area ( %p )", ARG1);
+//zz PRE_REG_READ1(int, "set_thread_area", struct user_desc *, u_info)
+//zz PRE_MEM_READ( "set_thread_area(u_info)", ARG1, sizeof(vki_modify_ldt_t) );
+//zz
+//zz /* "do" the syscall ourselves; the kernel never sees it */
+//zz SET_STATUS_( sys_set_thread_area( tid, (void *)ARG1 ) );
+//zz }
+//zz
+//zz PRE(sys_get_thread_area, Special)
+//zz {
+//zz PRINT("sys_get_thread_area ( %p )", ARG1);
+//zz PRE_REG_READ1(int, "get_thread_area", struct user_desc *, u_info)
+//zz PRE_MEM_WRITE( "get_thread_area(u_info)", ARG1, sizeof(vki_modify_ldt_t) );
+//zz
+//zz /* "do" the syscall ourselves; the kernel never sees it */
+//zz SET_STATUS_( sys_get_thread_area( tid, (void *)ARG1 ) );
+//zz
+//zz if (!VG_(is_kerror)(RES)) {
+//zz POST_MEM_WRITE( ARG1, sizeof(vki_modify_ldt_t) );
+//zz }
+//zz }
+//zz
+//zz // Parts of this are x86-specific, but the *PEEK* cases are generic.
+//zz // XXX: Why is the memory pointed to by ARG3 never checked?
+//zz PRE(sys_ptrace, 0)
+//zz {
+//zz PRINT("sys_ptrace ( %d, %d, %p, %p )", ARG1,ARG2,ARG3,ARG4);
+//zz PRE_REG_READ4(int, "ptrace",
+//zz long, request, long, pid, long, addr, long, data);
+//zz switch (ARG1) {
+//zz case VKI_PTRACE_PEEKTEXT:
+//zz case VKI_PTRACE_PEEKDATA:
+//zz case VKI_PTRACE_PEEKUSR:
+//zz PRE_MEM_WRITE( "ptrace(peek)", ARG4,
+//zz sizeof (long));
+//zz break;
+//zz case VKI_PTRACE_GETREGS:
+//zz PRE_MEM_WRITE( "ptrace(getregs)", ARG4,
+//zz sizeof (struct vki_user_regs_struct));
+//zz break;
+//zz case VKI_PTRACE_GETFPREGS:
+//zz PRE_MEM_WRITE( "ptrace(getfpregs)", ARG4,
+//zz sizeof (struct vki_user_i387_struct));
+//zz break;
+//zz case VKI_PTRACE_GETFPXREGS:
+//zz PRE_MEM_WRITE( "ptrace(getfpxregs)", ARG4,
+//zz sizeof(struct vki_user_fxsr_struct) );
+//zz break;
+//zz case VKI_PTRACE_SETREGS:
+//zz PRE_MEM_READ( "ptrace(setregs)", ARG4,
+//zz sizeof (struct vki_user_regs_struct));
+//zz break;
+//zz case VKI_PTRACE_SETFPREGS:
+//zz PRE_MEM_READ( "ptrace(setfpregs)", ARG4,
+//zz sizeof (struct vki_user_i387_struct));
+//zz break;
+//zz case VKI_PTRACE_SETFPXREGS:
+//zz PRE_MEM_READ( "ptrace(setfpxregs)", ARG4,
+//zz sizeof(struct vki_user_fxsr_struct) );
+//zz break;
+//zz default:
+//zz break;
+//zz }
+//zz }
+//zz
+//zz POST(sys_ptrace)
+//zz {
+//zz switch (ARG1) {
+//zz case VKI_PTRACE_PEEKTEXT:
+//zz case VKI_PTRACE_PEEKDATA:
+//zz case VKI_PTRACE_PEEKUSR:
+//zz POST_MEM_WRITE( ARG4, sizeof (long));
+//zz break;
+//zz case VKI_PTRACE_GETREGS:
+//zz POST_MEM_WRITE( ARG4, sizeof (struct vki_user_regs_struct));
+//zz break;
+//zz case VKI_PTRACE_GETFPREGS:
+//zz POST_MEM_WRITE( ARG4, sizeof (struct vki_user_i387_struct));
+//zz break;
+//zz case VKI_PTRACE_GETFPXREGS:
+//zz POST_MEM_WRITE( ARG4, sizeof(struct vki_user_fxsr_struct) );
+//zz break;
+//zz default:
+//zz break;
+//zz }
+//zz }
// XXX: this duplicates a function in coregrind/vg_syscalls.c, yuk
static Addr deref_Addr ( ThreadId tid, Addr a, Char* s )
@@ -1268,7 +1290,7 @@ static Addr deref_Addr ( ThreadId tid, Addr a, Char* s )
}
// XXX: should use the constants here (eg. SHMAT), not the numbers directly!
-PRE(sys_ipc, 0)
+PRE(sys_ipc)
{
PRINT("sys_ipc ( %d, %d, %d, %d, %p, %d )", ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
// XXX: this is simplistic -- some args are not used in all circumstances.
@@ -1279,7 +1301,7 @@ PRE(sys_ipc, 0)
switch (ARG1 /* call */) {
case VKI_SEMOP:
VG_(generic_PRE_sys_semop)( tid, ARG2, ARG5, ARG3 );
- /* tst->sys_flags |= MayBlock; */
+ *flags |= SfMayBlock;
break;
case VKI_SEMGET:
break;
@@ -1291,13 +1313,12 @@ PRE(sys_ipc, 0)
}
case VKI_SEMTIMEDOP:
VG_(generic_PRE_sys_semtimedop)( tid, ARG2, ARG5, ARG3, ARG6 );
- /* tst->sys_flags |= MayBlock; */
+ *flags |= SfMayBlock;
break;
case VKI_MSGSND:
VG_(generic_PRE_sys_msgsnd)( tid, ARG2, ARG5, ARG3, ARG4 );
- /* if ((ARG4 & VKI_IPC_NOWAIT) == 0)
- tst->sys_flags |= MayBlock;
- */
+ if ((ARG4 & VKI_IPC_NOWAIT) == 0)
+ *flags |= SfMayBlock;
break;
case VKI_MSGRCV:
{
@@ -1313,9 +1334,8 @@ PRE(sys_ipc, 0)
VG_(generic_PRE_sys_msgrcv)( tid, ARG2, msgp, ARG3, msgtyp, ARG4 );
- /* if ((ARG4 & VKI_IPC_NOWAIT) == 0)
- tst->sys_flags |= MayBlock;
- */
+ if ((ARG4 & VKI_IPC_NOWAIT) == 0)
+ *flags |= SfMayBlock;
break;
}
case VKI_MSGGET:
@@ -1324,14 +1344,19 @@ PRE(sys_ipc, 0)
VG_(generic_PRE_sys_msgctl)( tid, ARG2, ARG3, ARG5 );
break;
case VKI_SHMAT:
+ {
+ UWord w;
PRE_MEM_WRITE( "shmat(raddr)", ARG4, sizeof(Addr) );
- ARG5 = VG_(generic_PRE_sys_shmat)( tid, ARG2, ARG5, ARG3 );
- if (ARG5 == 0)
- SET_RESULT( -VKI_EINVAL );
+ w = VG_(generic_PRE_sys_shmat)( tid, ARG2, ARG5, ARG3 );
+ if (w == 0)
+ SET_STATUS_Failure( VKI_EINVAL );
+ else
+ ARG5 = w;
break;
+ }
case VKI_SHMDT:
if (!VG_(generic_PRE_sys_shmdt)(tid, ARG5))
- SET_RESULT( -VKI_EINVAL );
+ SET_STATUS_Failure( VKI_EINVAL );
break;
case VKI_SHMGET:
break;
@@ -1347,6 +1372,7 @@ PRE(sys_ipc, 0)
POST(sys_ipc)
{
+ vg_assert(SUCCESS);
switch (ARG1 /* call */) {
case VKI_SEMOP:
case VKI_SEMGET:
@@ -1412,90 +1438,471 @@ POST(sys_ipc)
}
}
+PRE(old_mmap)
+{
+ /* struct mmap_arg_struct {
+ unsigned long addr;
+ unsigned long len;
+ unsigned long prot;
+ unsigned long flags;
+ unsigned long fd;
+ unsigned long offset;
+ }; */
+ UWord a1, a2, a3, a4, a5, a6;
+
+ UWord* arg_block = (UWord*)ARG1;
+ PRE_REG_READ1(long, "old_mmap", struct mmap_arg_struct *, ARG1);
+ PRE_MEM_READ( "old_mmap(args)", (Addr)arg_block, 6*sizeof(UWord) );
+
+ a1 = arg_block[0];
+ a2 = arg_block[1];
+ a3 = arg_block[2];
+ a4 = arg_block[3];
+ a5 = arg_block[4];
+ a6 = arg_block[5];
+
+ PRINT("old_mmap ( %p, %llu, %d, %d, %d, %d )",
+ a1, (ULong)a2, a3, a4, a5, a6 );
+
+ if (a2 == 0) {
+ /* SuSV3 says: If len is zero, mmap() shall fail and no mapping
+ shall be established. */
+ SET_STATUS_Failure( VKI_EINVAL );
+ return;
+ }
+
+ if (/*(a4 & VKI_MAP_FIXED) &&*/ (0 != (a1 & (VKI_PAGE_SIZE-1)))) {
+ /* zap any misaligned addresses. */
+ SET_STATUS_Failure( VKI_EINVAL );
+ return;
+ }
-// jrs 20050207: this is from the svn branch
-//PRE(sys_sigaction, Special)
-//{
-// PRINT("sys_sigaction ( %d, %p, %p )", ARG1,ARG2,ARG3);
-// PRE_REG_READ3(int, "sigaction",
-// int, signum, const struct old_sigaction *, act,
-// struct old_sigaction *, oldact)
-// if (ARG2 != 0)
-// PRE_MEM_READ( "sigaction(act)", ARG2, sizeof(struct vki_old_sigaction));
-// if (ARG3 != 0)
-// PRE_MEM_WRITE( "sigaction(oldact)", ARG3, sizeof(struct vki_old_sigaction));
-//
-// VG_(do_sys_sigaction)(tid);
-//}
+ if (a4 & VKI_MAP_FIXED) {
+ if (!VG_(valid_client_addr)(a1, a2, tid, "old_mmap")) {
+ PRINT("old_mmap failing: %p-%p\n", a1, a1+a2);
+ SET_STATUS_Failure( VKI_ENOMEM );
+ }
+ } else {
+ Addr a = VG_(find_map_space)(a1, a2, True);
+ if (0) VG_(printf)("find_map_space(%p, %d) -> %p\n",a1,a2,a);
+ if (a == 0 && a1 != 0) {
+ a1 = VG_(find_map_space)(0, a2, True);
+ }
+ else
+ a1 = a;
+ if (a1 == 0)
+ SET_STATUS_Failure( VKI_ENOMEM );
+ else
+ a4 |= VKI_MAP_FIXED;
+ }
-/* Convert from non-RT to RT sigset_t's */
-static void convert_sigset_to_rt(const vki_old_sigset_t *oldset, vki_sigset_t *set)
+ if (! FAILURE) {
+ SysRes res = VG_(mmap_native)((void*)a1, a2, a3, a4, a5, a6);
+ SET_STATUS_from_SysRes(res);
+ if (!res.isError) {
+ vg_assert(VG_(valid_client_addr)(res.val, a2, tid, "old_mmap"));
+ VG_(mmap_segment)( (Addr)res.val, a2, a3, a4, a5, a6 );
+ }
+ }
+
+ if (0)
+ VG_(printf)("old_mmap( %p, fixed %d ) -> %s(%p)\n",
+ arg_block[0],
+ arg_block[3]&VKI_MAP_FIXED,
+ FAILURE ? "Fail" : "Success", RES_unchecked);
+
+ /* Stay sane */
+ if (SUCCESS && (arg_block[3] & VKI_MAP_FIXED))
+ vg_assert(RES == arg_block[0]);
+}
+
+// XXX: lstat64/fstat64/stat64 are generic, but not necessarily
+// applicable to every architecture -- I think only to 32-bit archs.
+// We're going to need something like linux/core_os32.h for such
+// things, eventually, I think. --njn
+PRE(sys_lstat64)
{
- VG_(sigemptyset)(set);
- set->sig[0] = *oldset;
+ PRINT("sys_lstat64 ( %p(%s), %p )",ARG1,ARG1,ARG2);
+ PRE_REG_READ2(long, "lstat64", char *, file_name, struct stat64 *, buf);
+ PRE_MEM_RASCIIZ( "lstat64(file_name)", ARG1 );
+ PRE_MEM_WRITE( "lstat64(buf)", ARG2, sizeof(struct vki_stat64) );
}
-PRE(sys_sigaction, Special)
+
+POST(sys_lstat64)
{
- struct vki_sigaction new, old;
- struct vki_sigaction *newp, *oldp;
+ vg_assert(SUCCESS);
+ if (RES == 0) {
+ POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
+ }
+}
- PRINT("sys_sigaction ( %d, %p, %p )", ARG1,ARG2,ARG3);
- PRE_REG_READ3(int, "sigaction",
- int, signum, const struct old_sigaction *, act,
- struct old_sigaction *, oldact);
+PRE(sys_stat64)
+{
+ PRINT("sys_stat64 ( %p, %p )",ARG1,ARG2);
+ PRE_REG_READ2(long, "stat64", char *, file_name, struct stat64 *, buf);
+ PRE_MEM_RASCIIZ( "stat64(file_name)", ARG1 );
+ PRE_MEM_WRITE( "stat64(buf)", ARG2, sizeof(struct vki_stat64) );
+}
- newp = oldp = NULL;
+POST(sys_stat64)
+{
+ POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
+}
- if (ARG2 != 0)
- PRE_MEM_READ( "sigaction(act)", ARG2, sizeof(struct vki_old_sigaction));
+PRE(sys_fstat64)
+{
+ PRINT("sys_fstat64 ( %d, %p )",ARG1,ARG2);
+ PRE_REG_READ2(long, "fstat64", unsigned long, fd, struct stat64 *, buf);
+ PRE_MEM_WRITE( "fstat64(buf)", ARG2, sizeof(struct vki_stat64) );
+}
- if (ARG3 != 0) {
- PRE_MEM_WRITE( "sigaction(oldact)", ARG3, sizeof(struct vki_old_sigaction));
- oldp = &old;
- }
+POST(sys_fstat64)
+{
+ POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
+}
+
+PRE(sys_socketcall)
+{
+# define ARG2_0 (((UWord*)ARG2)[0])
+# define ARG2_1 (((UWord*)ARG2)[1])
+# define ARG2_2 (((UWord*)ARG2)[2])
+# define ARG2_3 (((UWord*)ARG2)[3])
+# define ARG2_4 (((UWord*)ARG2)[4])
+# define ARG2_5 (((UWord*)ARG2)[5])
+
+ *flags |= SfMayBlock;
+ PRINT("sys_socketcall ( %d, %p )",ARG1,ARG2);
+ PRE_REG_READ2(long, "socketcall", int, call, unsigned long *, args);
+
+ switch (ARG1 /* request */) {
+
+ case VKI_SYS_SOCKETPAIR:
+ /* int socketpair(int d, int type, int protocol, int sv[2]); */
+ PRE_MEM_READ( "socketcall.socketpair(args)", ARG2, 4*sizeof(Addr) );
+ VG_(generic_PRE_sys_socketpair)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
+ break;
- //jrs 20050207: what?! how can this make any sense?
- //if (VG_(is_kerror)(SYSRES))
- // return;
+ case VKI_SYS_SOCKET:
+ /* int socket(int domain, int type, int protocol); */
+ PRE_MEM_READ( "socketcall.socket(args)", ARG2, 3*sizeof(Addr) );
+ break;
- if (ARG2 != 0) {
- struct vki_old_sigaction *oldnew = (struct vki_old_sigaction *)ARG2;
+ case VKI_SYS_BIND:
+ /* int bind(int sockfd, struct sockaddr *my_addr,
+ int addrlen); */
+ PRE_MEM_READ( "socketcall.bind(args)", ARG2, 3*sizeof(Addr) );
+ VG_(generic_PRE_sys_bind)( tid, ARG2_0, ARG2_1, ARG2_2 );
+ break;
+
+ case VKI_SYS_LISTEN:
+ /* int listen(int s, int backlog); */
+ PRE_MEM_READ( "socketcall.listen(args)", ARG2, 2*sizeof(Addr) );
+ break;
- new.ksa_handler = oldnew->ksa_handler;
- new.sa_flags = oldnew->sa_flags;
- new.sa_restorer = oldnew->sa_restorer;
- convert_sigset_to_rt(&oldnew->sa_mask, &new.sa_mask);
- newp = &new;
+ case VKI_SYS_ACCEPT: {
+ /* int accept(int s, struct sockaddr *addr, int *addrlen); */
+ PRE_MEM_READ( "socketcall.accept(args)", ARG2, 3*sizeof(Addr) );
+ VG_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
+ break;
}
- SET_RESULT( VG_(do_sys_sigaction)(ARG1, newp, oldp) );
+ case VKI_SYS_SENDTO:
+ /* int sendto(int s, const void *msg, int len,
+ unsigned int flags,
+ const struct sockaddr *to, int tolen); */
+ PRE_MEM_READ( "socketcall.sendto(args)", ARG2, 6*sizeof(Addr) );
+ VG_(generic_PRE_sys_sendto)( tid, ARG2_0, ARG2_1, ARG2_2,
+ ARG2_3, ARG2_4, ARG2_5 );
+ break;
+
+ case VKI_SYS_SEND:
+ /* int send(int s, const void *msg, size_t len, int flags); */
+ PRE_MEM_READ( "socketcall.send(args)", ARG2, 4*sizeof(Addr) );
+ VG_(generic_PRE_sys_send)( tid, ARG2_0, ARG2_1, ARG2_2 );
+ break;
- if (ARG3 != 0 && RES == 0) {
- struct vki_old_sigaction *oldold = (struct vki_old_sigaction *)ARG3;
+ case VKI_SYS_RECVFROM:
+ /* int recvfrom(int s, void *buf, int len, unsigned int flags,
+ struct sockaddr *from, int *fromlen); */
+ PRE_MEM_READ( "socketcall.recvfrom(args)", ARG2, 6*sizeof(Addr) );
+ VG_(generic_PRE_sys_recvfrom)( tid, ARG2_0, ARG2_1, ARG2_2,
+ ARG2_3, ARG2_4, ARG2_5 );
+ break;
+
+ case VKI_SYS_RECV:
+ /* int recv(int s, void *buf, int len, unsigned int flags); */
+ /* man 2 recv says:
+ The recv call is normally used only on a connected socket
+ (see connect(2)) and is identical to recvfrom with a NULL
+ from parameter.
+ */
+ PRE_MEM_READ( "socketcall.recv(args)", ARG2, 4*sizeof(Addr) );
+ VG_(generic_PRE_sys_recv)( tid, ARG2_0, ARG2_1, ARG2_2 );
+ break;
- oldold->ksa_handler = oldp->ksa_handler;
- oldold->sa_flags = oldp->sa_flags;
- oldold->sa_restorer = oldp->sa_restorer;
- oldold->sa_mask = oldp->sa_mask.sig[0];
+ case VKI_SYS_CONNECT:
+ /* int connect(int sockfd,
+ struct sockaddr *serv_addr, int addrlen ); */
+ PRE_MEM_READ( "socketcall.connect(args)", ARG2, 3*sizeof(Addr) );
+ VG_(generic_PRE_sys_connect)( tid, ARG2_0, ARG2_1, ARG2_2 );
+ break;
+
+ case VKI_SYS_SETSOCKOPT:
+ /* int setsockopt(int s, int level, int optname,
+ const void *optval, int optlen); */
+ PRE_MEM_READ( "socketcall.setsockopt(args)", ARG2, 5*sizeof(Addr) );
+ VG_(generic_PRE_sys_setsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
+ ARG2_3, ARG2_4 );
+ break;
+
+ case VKI_SYS_GETSOCKOPT:
+ /* int getsockopt(int s, int level, int optname,
+ void *optval, socklen_t *optlen); */
+ PRE_MEM_READ( "socketcall.getsockopt(args)", ARG2, 5*sizeof(Addr) );
+ VG_(generic_PRE_sys_getsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
+ ARG2_3, ARG2_4 );
+ break;
+
+ case VKI_SYS_GETSOCKNAME:
+ /* int getsockname(int s, struct sockaddr* name, int* namelen) */
+ PRE_MEM_READ( "socketcall.getsockname(args)", ARG2, 3*sizeof(Addr) );
+ VG_(generic_PRE_sys_getsockname)( tid, ARG2_0, ARG2_1, ARG2_2 );
+ break;
+
+ case VKI_SYS_GETPEERNAME:
+ /* int getpeername(int s, struct sockaddr* name, int* namelen) */
+ PRE_MEM_READ( "socketcall.getpeername(args)", ARG2, 3*sizeof(Addr) );
+ VG_(generic_PRE_sys_getpeername)( tid, ARG2_0, ARG2_1, ARG2_2 );
+ break;
+
+ case VKI_SYS_SHUTDOWN:
+ /* int shutdown(int s, int how); */
+ PRE_MEM_READ( "socketcall.shutdown(args)", ARG2, 2*sizeof(Addr) );
+ break;
+
+ case VKI_SYS_SENDMSG: {
+ /* int sendmsg(int s, const struct msghdr *msg, int flags); */
+
+ /* this causes warnings, and I don't get why. glibc bug?
+ * (after all it's glibc providing the arguments array)
+ PRE_MEM_READ( "socketcall.sendmsg(args)", ARG2, 3*sizeof(Addr) );
+ */
+ VG_(generic_PRE_sys_sendmsg)( tid, ARG2_0, ARG2_1 );
+ break;
+ }
+
+ case VKI_SYS_RECVMSG: {
+ /* int recvmsg(int s, struct msghdr *msg, int flags); */
+
+ /* this causes warnings, and I don't get why. glibc bug?
+ * (after all it's glibc providing the arguments array)
+ PRE_MEM_READ("socketcall.recvmsg(args)", ARG2, 3*sizeof(Addr) );
+ */
+ VG_(generic_PRE_sys_recvmsg)( tid, ARG2_0, ARG2_1 );
+ break;
+ }
+
+ default:
+ VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%x",ARG1);
+ SET_STATUS_Failure( VKI_EINVAL );
+ break;
}
+# undef ARG2_0
+# undef ARG2_1
+# undef ARG2_2
+# undef ARG2_3
+# undef ARG2_4
+# undef ARG2_5
}
-POST(sys_sigaction)
+POST(sys_socketcall)
{
- if (RES == 0 && ARG3 != 0)
- POST_MEM_WRITE( ARG3, sizeof(struct vki_old_sigaction));
+# define ARG2_0 (((UWord*)ARG2)[0])
+# define ARG2_1 (((UWord*)ARG2)[1])
+# define ARG2_2 (((UWord*)ARG2)[2])
+# define ARG2_3 (((UWord*)ARG2)[3])
+# define ARG2_4 (((UWord*)ARG2)[4])
+# define ARG2_5 (((UWord*)ARG2)[5])
+
+ SysRes r;
+ vg_assert(SUCCESS);
+ switch (ARG1 /* request */) {
+
+ case VKI_SYS_SOCKETPAIR:
+ r = VG_(generic_POST_sys_socketpair)(
+ tid, VG_(mk_SysRes_Success)(RES),
+ ARG2_0, ARG2_1, ARG2_2, ARG2_3
+ );
+ SET_STATUS_from_SysRes(r);
+ break;
+
+ case VKI_SYS_SOCKET:
+ r = VG_(generic_POST_sys_socket)( tid, VG_(mk_SysRes_Success)(RES) );
+ SET_STATUS_from_SysRes(r);
+ break;
+
+ case VKI_SYS_BIND:
+ /* int bind(int sockfd, struct sockaddr *my_addr,
+ int addrlen); */
+ break;
+
+ case VKI_SYS_LISTEN:
+ /* int listen(int s, int backlog); */
+ break;
+
+ case VKI_SYS_ACCEPT:
+ /* int accept(int s, struct sockaddr *addr, int *addrlen); */
+ r = VG_(generic_POST_sys_accept)( tid, VG_(mk_SysRes_Success)(RES),
+ ARG2_0, ARG2_1, ARG2_2 );
+ SET_STATUS_from_SysRes(r);
+ break;
+
+ case VKI_SYS_SENDTO:
+ break;
+
+ case VKI_SYS_SEND:
+ break;
+
+ case VKI_SYS_RECVFROM:
+ VG_(generic_POST_sys_recvfrom)( tid, VG_(mk_SysRes_Success)(RES),
+ ARG2_0, ARG2_1, ARG2_2,
+ ARG2_3, ARG2_4, ARG2_5 );
+ break;
+
+ case VKI_SYS_RECV:
+ VG_(generic_POST_sys_recv)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
+ break;
+
+ case VKI_SYS_CONNECT:
+ break;
+
+ case VKI_SYS_SETSOCKOPT:
+ break;
+
+ case VKI_SYS_GETSOCKOPT:
+ VG_(generic_POST_sys_getsockopt)( tid, VG_(mk_SysRes_Success)(RES),
+ ARG2_0, ARG2_1,
+ ARG2_2, ARG2_3, ARG2_4 );
+ break;
+
+ case VKI_SYS_GETSOCKNAME:
+ VG_(generic_POST_sys_getsockname)( tid, VG_(mk_SysRes_Success)(RES),
+ ARG2_0, ARG2_1, ARG2_2 );
+ break;
+
+ case VKI_SYS_GETPEERNAME:
+ VG_(generic_POST_sys_getpeername)( tid, VG_(mk_SysRes_Success)(RES),
+ ARG2_0, ARG2_1, ARG2_2 );
+ break;
+
+ case VKI_SYS_SHUTDOWN:
+ break;
+
+ case VKI_SYS_SENDMSG:
+ break;
+
+ case VKI_SYS_RECVMSG:
+ VG_(generic_POST_sys_recvmsg)( tid, ARG2_0, ARG2_1 );
+ break;
+
+ default:
+ VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%x",ARG1);
+ VG_(core_panic)("... bye!\n");
+ break; /*NOTREACHED*/
+ }
+# undef ARG2_0
+# undef ARG2_1
+# undef ARG2_2
+# undef ARG2_3
+# undef ARG2_4
+# undef ARG2_5
}
-#undef PRE
-#undef POST
+//zz // jrs 20050207: this is from the svn branch
+//zz //PRE(sys_sigaction, Special)
+//zz //{
+//zz // PRINT("sys_sigaction ( %d, %p, %p )", ARG1,ARG2,ARG3);
+//zz // PRE_REG_READ3(int, "sigaction",
+//zz // int, signum, const struct old_sigaction *, act,
+//zz // struct old_sigaction *, oldact)
+//zz // if (ARG2 != 0)
+//zz // PRE_MEM_READ( "sigaction(act)", ARG2, sizeof(struct vki_old_sigaction));
+//zz // if (ARG3 != 0)
+//zz // PRE_MEM_WRITE( "sigaction(oldact)", ARG3, sizeof(struct vki_old_sigaction));
+//zz //
+//zz // VG_(do_sys_sigaction)(tid);
+//zz //}
+//zz
+//zz /* Convert from non-RT to RT sigset_t's */
+//zz static void convert_sigset_to_rt(const vki_old_sigset_t *oldset, vki_sigset_t *set)
+//zz {
+//zz VG_(sigemptyset)(set);
+//zz set->sig[0] = *oldset;
+//zz }
+//zz PRE(sys_sigaction, Special)
+//zz {
+//zz struct vki_sigaction new, old;
+//zz struct vki_sigaction *newp, *oldp;
+//zz
+//zz PRINT("sys_sigaction ( %d, %p, %p )", ARG1,ARG2,ARG3);
+//zz PRE_REG_READ3(int, "sigaction",
+//zz int, signum, const struct old_sigaction *, act,
+//zz struct old_sigaction *, oldact);
+//zz
+//zz newp = oldp = NULL;
+//zz
+//zz if (ARG2 != 0)
+//zz PRE_MEM_READ( "sigaction(act)", ARG2, sizeof(struct vki_old_sigaction));
+//zz
+//zz if (ARG3 != 0) {
+//zz PRE_MEM_WRITE( "sigaction(oldact)", ARG3, sizeof(struct vki_old_sigaction));
+//zz oldp = &old;
+//zz }
+//zz
+//zz //jrs 20050207: what?! how can this make any sense?
+//zz //if (VG_(is_kerror)(SYSRES))
+//zz // return;
+//zz
+//zz if (ARG2 != 0) {
+//zz struct vki_old_sigaction *oldnew = (struct vki_old_sigaction *)ARG2;
+//zz
+//zz new.ksa_handler = oldnew->ksa_handler;
+//zz new.sa_flags = oldnew->sa_flags;
+//zz new.sa_restorer = oldnew->sa_restorer;
+//zz convert_sigset_to_rt(&oldnew->sa_mask, &new.sa_mask);
+//zz newp = &new;
+//zz }
+//zz
+//zz SET_STATUS_( VG_(do_sys_sigaction)(ARG1, newp, oldp) );
+//zz
+//zz if (ARG3 != 0 && RES == 0) {
+//zz struct vki_old_sigaction *oldold = (struct vki_old_sigaction *)ARG3;
+//zz
+//zz oldold->ksa_handler = oldp->ksa_handler;
+//zz oldold->sa_flags = oldp->sa_flags;
+//zz oldold->sa_restorer = oldp->sa_restorer;
+//zz oldold->sa_mask = oldp->sa_mask.sig[0];
+//zz }
+//zz }
+//zz
+//zz POST(sys_sigaction)
+//zz {
+//zz if (RES == 0 && ARG3 != 0)
+//zz POST_MEM_WRITE( ARG3, sizeof(struct vki_old_sigaction));
+//zz }
+//zz
+//zz #undef PRE
+//zz #undef POST
/* ---------------------------------------------------------------------
The x86/Linux syscall table
------------------------------------------------------------------ */
-// Macros for adding x86/Linux-specific wrappers to the syscall table.
-#define PLAX_(const, name) SYS_WRAPPER_ENTRY_X_(x86_linux, const, name)
-#define PLAXY(const, name) SYS_WRAPPER_ENTRY_XY(x86_linux, const, name)
+/* Add a Linux-specific, arch-independent wrapper to a syscall
+ table. */
+#define PLAX_(sysno, name) WRAPPER_ENTRY_X_(x86_linux, sysno, name)
+#define PLAXY(sysno, name) WRAPPER_ENTRY_XY(x86_linux, sysno, name)
+
// This table maps from __NR_xxx syscall numbers (from
// linux/include/asm-i386/unistd.h) to the appropriate PRE/POST sys_foo()
@@ -1505,8 +1912,8 @@ POST(sys_sigaction)
// arch/OS combination, eg. */* (generic), */Linux (Linux only), ?/?
// (unknown).
-const struct SyscallTableEntry VGA_(syscall_table)[] = {
- // (restart_syscall) // 0
+const SyscallTableEntry VGP_(syscall_table)[] = {
+//zz // (restart_syscall) // 0
GENX_(__NR_exit, sys_exit), // 1
GENX_(__NR_fork, sys_fork), // 2
GENXY(__NR_read, sys_read), // 3
@@ -1525,9 +1932,9 @@ const struct SyscallTableEntry VGA_(syscall_table)[] = {
GENX_(__NR_mknod, sys_mknod), // 14
GENX_(__NR_chmod, sys_chmod), // 15
- // (__NR_lchown, sys_lchown16), // 16 ## P
+//zz // (__NR_lchown, sys_lchown16), // 16 ## P
GENX_(__NR_break, sys_ni_syscall), // 17
- // (__NR_oldstat, sys_stat), // 18 (obsolete)
+//zz // (__NR_oldstat, sys_stat), // 18 (obsolete)
GENX_(__NR_lseek, sys_lseek), // 19
GENX_(__NR_getpid, sys_getpid), // 20
@@ -1535,324 +1942,324 @@ const struct SyscallTableEntry VGA_(syscall_table)[] = {
LINX_(__NR_umount, sys_oldumount), // 22
GENX_(__NR_setuid, sys_setuid16), // 23 ## P
GENX_(__NR_getuid, sys_getuid16), // 24 ## P
-
- // (__NR_stime, sys_stime), // 25 * (SVr4,SVID,X/OPEN)
- PLAXY(__NR_ptrace, sys_ptrace), // 26
+//zz
+//zz // (__NR_stime, sys_stime), // 25 * (SVr4,SVID,X/OPEN)
+//zz PLAXY(__NR_ptrace, sys_ptrace), // 26
GENX_(__NR_alarm, sys_alarm), // 27
- // (__NR_oldfstat, sys_fstat), // 28 * L -- obsolete
+//zz // (__NR_oldfstat, sys_fstat), // 28 * L -- obsolete
GENX_(__NR_pause, sys_pause), // 29
-
- GENX_(__NR_utime, sys_utime), // 30
+//zz
+//zz GENX_(__NR_utime, sys_utime), // 30
GENX_(__NR_stty, sys_ni_syscall), // 31
GENX_(__NR_gtty, sys_ni_syscall), // 32
GENX_(__NR_access, sys_access), // 33
- GENX_(__NR_nice, sys_nice), // 34
-
+//zz GENX_(__NR_nice, sys_nice), // 34
+//zz
GENX_(__NR_ftime, sys_ni_syscall), // 35
- GENX_(__NR_sync, sys_sync), // 36
+//zz GENX_(__NR_sync, sys_sync), // 36
GENX_(__NR_kill, sys_kill), // 37
GENX_(__NR_rename, sys_rename), // 38
GENX_(__NR_mkdir, sys_mkdir), // 39
-
- GENX_(__NR_rmdir, sys_rmdir), // 40
+//zz
+//zz GENX_(__NR_rmdir, sys_rmdir), // 40
GENXY(__NR_dup, sys_dup), // 41
GENXY(__NR_pipe, sys_pipe), // 42
- GENXY(__NR_times, sys_times), // 43
+//zz GENXY(__NR_times, sys_times), // 43
GENX_(__NR_prof, sys_ni_syscall), // 44
-
+//zz
GENX_(__NR_brk, sys_brk), // 45
- GENX_(__NR_setgid, sys_setgid16), // 46
- GENX_(__NR_getgid, sys_getgid16), // 47
- // (__NR_signal, sys_signal), // 48 */* (ANSI C)
+//zz GENX_(__NR_setgid, sys_setgid16), // 46
+//zz GENX_(__NR_getgid, sys_getgid16), // 47
+//zz // (__NR_signal, sys_signal), // 48 */* (ANSI C)
GENX_(__NR_geteuid, sys_geteuid16), // 49
-
- GENX_(__NR_getegid, sys_getegid16), // 50
- GENX_(__NR_acct, sys_acct), // 51
- LINX_(__NR_umount2, sys_umount), // 52
+//zz
+//zz GENX_(__NR_getegid, sys_getegid16), // 50
+//zz GENX_(__NR_acct, sys_acct), // 51
+//zz LINX_(__NR_umount2, sys_umount), // 52
GENX_(__NR_lock, sys_ni_syscall), // 53
GENXY(__NR_ioctl, sys_ioctl), // 54
-
- GENXY(__NR_fcntl, sys_fcntl), // 55
+//zz
+//zz GENXY(__NR_fcntl, sys_fcntl), // 55
GENX_(__NR_mpx, sys_ni_syscall), // 56
- GENX_(__NR_setpgid, sys_setpgid), // 57
+//zz GENX_(__NR_setpgid, sys_setpgid), // 57
GENX_(__NR_ulimit, sys_ni_syscall), // 58
- // (__NR_oldolduname, sys_olduname), // 59 Linux -- obsolete
-
- GENX_(__NR_umask, sys_umask), // 60
- GENX_(__NR_chroot, sys_chroot), // 61
- // (__NR_ustat, sys_ustat) // 62 SVr4 -- deprecated
+//zz // (__NR_oldolduname, sys_olduname), // 59 Linux -- obsolete
+//zz
+//zz GENX_(__NR_umask, sys_umask), // 60
+//zz GENX_(__NR_chroot, sys_chroot), // 61
+//zz // (__NR_ustat, sys_ustat) // 62 SVr4 -- deprecated
GENXY(__NR_dup2, sys_dup2), // 63
GENX_(__NR_getppid, sys_getppid), // 64
-
- GENX_(__NR_getpgrp, sys_getpgrp), // 65
- GENX_(__NR_setsid, sys_setsid), // 66
- PLAXY(__NR_sigaction, sys_sigaction), // 67
- // (__NR_sgetmask, sys_sgetmask), // 68 */* (ANSI C)
- // (__NR_ssetmask, sys_ssetmask), // 69 */* (ANSI C)
-
- GENX_(__NR_setreuid, sys_setreuid16), // 70
- GENX_(__NR_setregid, sys_setregid16), // 71
- GENX_(__NR_sigsuspend, sys_sigsuspend), // 72
- GENXY(__NR_sigpending, sys_sigpending), // 73
- // (__NR_sethostname, sys_sethostname), // 74 */*
-
+//zz
+//zz GENX_(__NR_getpgrp, sys_getpgrp), // 65
+//zz GENX_(__NR_setsid, sys_setsid), // 66
+//zz PLAXY(__NR_sigaction, sys_sigaction), // 67
+//zz // (__NR_sgetmask, sys_sgetmask), // 68 */* (ANSI C)
+//zz // (__NR_ssetmask, sys_ssetmask), // 69 */* (ANSI C)
+//zz
+//zz GENX_(__NR_setreuid, sys_setreuid16), // 70
+//zz GENX_(__NR_setregid, sys_setregid16), // 71
+//zz GENX_(__NR_sigsuspend, sys_sigsuspend), // 72
+//zz GENXY(__NR_sigpending, sys_sigpending), // 73
+//zz // (__NR_sethostname, sys_sethostname), // 74 */*
+//zz
GENX_(__NR_setrlimit, sys_setrlimit), // 75
- GENXY(__NR_getrlimit, sys_old_getrlimit), // 76
- GENXY(__NR_getrusage, sys_getrusage), // 77
+//zz GENXY(__NR_getrlimit, sys_old_getrlimit), // 76
+//zz GENXY(__NR_getrusage, sys_getrusage), // 77
GENXY(__NR_gettimeofday, sys_gettimeofday), // 78
- GENX_(__NR_settimeofday, sys_settimeofday), // 79
-
- GENXY(__NR_getgroups, sys_getgroups16), // 80
- GENX_(__NR_setgroups, sys_setgroups16), // 81
- PLAX_(__NR_select, old_select), // 82
- GENX_(__NR_symlink, sys_symlink), // 83
- // (__NR_oldlstat, sys_lstat), // 84 -- obsolete
-
+//zz GENX_(__NR_settimeofday, sys_settimeofday), // 79
+//zz
+//zz GENXY(__NR_getgroups, sys_getgroups16), // 80
+//zz GENX_(__NR_setgroups, sys_setgroups16), // 81
+//zz PLAX_(__NR_select, old_select), // 82
+//zz GENX_(__NR_symlink, sys_symlink), // 83
+//zz // (__NR_oldlstat, sys_lstat), // 84 -- obsolete
+//zz
GENX_(__NR_readlink, sys_readlink), // 85
- // (__NR_uselib, sys_uselib), // 86 */Linux
- // (__NR_swapon, sys_swapon), // 87 */Linux
- // (__NR_reboot, sys_reboot), // 88 */Linux
- // (__NR_readdir, old_readdir), // 89 -- superseded
-
- GENX_(__NR_mmap, old_mmap), // 90
+//zz // (__NR_uselib, sys_uselib), // 86 */Linux
+//zz // (__NR_swapon, sys_swapon), // 87 */Linux
+//zz // (__NR_reboot, sys_reboot), // 88 */Linux
+//zz // (__NR_readdir, old_readdir), // 89 -- superseded
+//zz
+ PLAX_(__NR_mmap, old_mmap), // 90
GENXY(__NR_munmap, sys_munmap), // 91
- GENX_(__NR_truncate, sys_truncate), // 92
- GENX_(__NR_ftruncate, sys_ftruncate), // 93
- GENX_(__NR_fchmod, sys_fchmod), // 94
-
- GENX_(__NR_fchown, sys_fchown16), // 95
- GENX_(__NR_getpriority, sys_getpriority), // 96
- GENX_(__NR_setpriority, sys_setpriority), // 97
+//zz GENX_(__NR_truncate, sys_truncate), // 92
+//zz GENX_(__NR_ftruncate, sys_ftruncate), // 93
+//zz GENX_(__NR_fchmod, sys_fchmod), // 94
+//zz
+//zz GENX_(__NR_fchown, sys_fchown16), // 95
+//zz GENX_(__NR_getpriority, sys_getpriority), // 96
+//zz GENX_(__NR_setpriority, sys_setpriority), // 97
GENX_(__NR_profil, sys_ni_syscall), // 98
- GENXY(__NR_statfs, sys_statfs), // 99
-
- GENXY(__NR_fstatfs, sys_fstatfs), // 100
- LINX_(__NR_ioperm, sys_ioperm), // 101
- GENXY(__NR_socketcall, sys_socketcall), // 102
- LINXY(__NR_syslog, sys_syslog), // 103
- GENXY(__NR_setitimer, sys_setitimer), // 104
-
- GENXY(__NR_getitimer, sys_getitimer), // 105
- GENXY(__NR_stat, sys_newstat), // 106
- GENXY(__NR_lstat, sys_newlstat), // 107
- GENXY(__NR_fstat, sys_newfstat), // 108
- // (__NR_olduname, sys_uname), // 109 -- obsolete
-
- GENX_(__NR_iopl, sys_iopl), // 110
- LINX_(__NR_vhangup, sys_vhangup), // 111
+//zz GENXY(__NR_statfs, sys_statfs), // 99
+//zz
+//zz GENXY(__NR_fstatfs, sys_fstatfs), // 100
+//zz LINX_(__NR_ioperm, sys_ioperm), // 101
+ PLAXY(__NR_socketcall, sys_socketcall), // 102 x86/Linux-only
+//zz LINXY(__NR_syslog, sys_syslog), // 103
+//zz GENXY(__NR_setitimer, sys_setitimer), // 104
+//zz
+//zz GENXY(__NR_getitimer, sys_getitimer), // 105
+//zz GENXY(__NR_stat, sys_newstat), // 106
+//zz GENXY(__NR_lstat, sys_newlstat), // 107
+//zz GENXY(__NR_fstat, sys_newfstat), // 108
+//zz // (__NR_olduname, sys_uname), // 109 -- obsolete
+//zz
+//zz GENX_(__NR_iopl, sys_iopl), // 110
+//zz LINX_(__NR_vhangup, sys_vhangup), // 111
GENX_(__NR_idle, sys_ni_syscall), // 112
- // (__NR_vm86old, sys_vm86old), // 113 x86/Linux-only
+//zz // (__NR_vm86old, sys_vm86old), // 113 x86/Linux-only
GENXY(__NR_wait4, sys_wait4), // 114
-
- // (__NR_swapoff, sys_swapoff), // 115 */Linux
- LINXY(__NR_sysinfo, sys_sysinfo), // 116
+//zz
+//zz // (__NR_swapoff, sys_swapoff), // 115 */Linux
+//zz LINXY(__NR_sysinfo, sys_sysinfo), // 116
PLAXY(__NR_ipc, sys_ipc), // 117
- GENX_(__NR_fsync, sys_fsync), // 118
+//zz GENX_(__NR_fsync, sys_fsync), // 118
PLAX_(__NR_sigreturn, sys_sigreturn), // 119 ?/Linux
PLAX_(__NR_clone, sys_clone), // 120
- // (__NR_setdomainname, sys_setdomainname), // 121 */*(?)
+//zz // (__NR_setdomainname, sys_setdomainname), // 121 */*(?)
GENXY(__NR_uname, sys_newuname), // 122
PLAX_(__NR_modify_ldt, sys_modify_ldt), // 123
- LINXY(__NR_adjtimex, sys_adjtimex), // 124
-
+//zz LINXY(__NR_adjtimex, sys_adjtimex), // 124
+//zz
GENXY(__NR_mprotect, sys_mprotect), // 125
GENXY(__NR_sigprocmask, sys_sigprocmask), // 126
- // Nb: create_module() was removed 2.4-->2.6
+//zz // Nb: create_module() was removed 2.4-->2.6
GENX_(__NR_create_module, sys_ni_syscall), // 127
- GENX_(__NR_init_module, sys_init_module), // 128
- // (__NR_delete_module, sys_delete_module), // 129 (*/Linux)?
-
- // Nb: get_kernel_syms() was removed 2.4-->2.6
+//zz GENX_(__NR_init_module, sys_init_module), // 128
+//zz // (__NR_delete_module, sys_delete_module), // 129 (*/Linux)?
+//zz
+//zz // Nb: get_kernel_syms() was removed 2.4-->2.6
GENX_(__NR_get_kernel_syms, sys_ni_syscall), // 130
- GENX_(__NR_quotactl, sys_quotactl), // 131
- GENX_(__NR_getpgid, sys_getpgid), // 132
- GENX_(__NR_fchdir, sys_fchdir), // 133
- // (__NR_bdflush, sys_bdflush), // 134 */Linux
-
- // (__NR_sysfs, sys_sysfs), // 135 SVr4
- LINX_(__NR_personality, sys_personality), // 136
+//zz GENX_(__NR_quotactl, sys_quotactl), // 131
+//zz GENX_(__NR_getpgid, sys_getpgid), // 132
+//zz GENX_(__NR_fchdir, sys_fchdir), // 133
+//zz // (__NR_bdflush, sys_bdflush), // 134 */Linux
+//zz
+//zz // (__NR_sysfs, sys_sysfs), // 135 SVr4
+//zz LINX_(__NR_personality, sys_personality), // 136
GENX_(__NR_afs_syscall, sys_ni_syscall), // 137
- LINX_(__NR_setfsuid, sys_setfsuid16), // 138
- LINX_(__NR_setfsgid, sys_setfsgid16), // 139
-
+//zz LINX_(__NR_setfsuid, sys_setfsuid16), // 138
+//zz LINX_(__NR_setfsgid, sys_setfsgid16), // 139
+//zz
LINXY(__NR__llseek, sys_llseek), // 140
- GENXY(__NR_getdents, sys_getdents), // 141
+//zz GENXY(__NR_getdents, sys_getdents), // 141
GENX_(__NR__newselect, sys_select), // 142
- GENX_(__NR_flock, sys_flock), // 143
- GENX_(__NR_msync, sys_msync), // 144
-
+//zz GENX_(__NR_flock, sys_flock), // 143
+//zz GENX_(__NR_msync, sys_msync), // 144
+//zz
GENXY(__NR_readv, sys_readv), // 145
GENX_(__NR_writev, sys_writev), // 146
- GENX_(__NR_getsid, sys_getsid), // 147
- GENX_(__NR_fdatasync, sys_fdatasync), // 148
+//zz GENX_(__NR_getsid, sys_getsid), // 147
+//zz GENX_(__NR_fdatasync, sys_fdatasync), // 148
LINXY(__NR__sysctl, sys_sysctl), // 149
-
- GENX_(__NR_mlock, sys_mlock), // 150
- GENX_(__NR_munlock, sys_munlock), // 151
- GENX_(__NR_mlockall, sys_mlockall), // 152
- GENX_(__NR_munlockall, sys_munlockall), // 153
- GENXY(__NR_sched_setparam, sys_sched_setparam), // 154
-
- GENXY(__NR_sched_getparam, sys_sched_getparam), // 155
- GENX_(__NR_sched_setscheduler, sys_sched_setscheduler), // 156
- GENX_(__NR_sched_getscheduler, sys_sched_getscheduler), // 157
- GENX_(__NR_sched_yield, sys_sched_yield), // 158
- GENX_(__NR_sched_get_priority_max, sys_sched_get_priority_max),// 159
-
- GENX_(__NR_sched_get_priority_min, sys_sched_get_priority_min),// 160
- // (__NR_sched_rr_get_interval, sys_sched_rr_get_interval), // 161 */*
+//zz
+//zz GENX_(__NR_mlock, sys_mlock), // 150
+//zz GENX_(__NR_munlock, sys_munlock), // 151
+//zz GENX_(__NR_mlockall, sys_mlockall), // 152
+//zz GENX_(__NR_munlockall, sys_munlockall), // 153
+//zz GENXY(__NR_sched_setparam, sys_sched_setparam), // 154
+//zz
+//zz GENXY(__NR_sched_getparam, sys_sched_getparam), // 155
+//zz GENX_(__NR_sched_setscheduler, sys_sched_setscheduler), // 156
+//zz GENX_(__NR_sched_getscheduler, sys_sched_getscheduler), // 157
+//zz GENX_(__NR_sched_yield, sys_sched_yield), // 158
+//zz GENX_(__NR_sched_get_priority_max, sys_sched_get_priority_max),// 159
+//zz
+//zz GENX_(__NR_sched_get_priority_min, sys_sched_get_priority_min),// 160
+//zz // (__NR_sched_rr_get_interval, sys_sched_rr_get_interval), // 161 */*
GENXY(__NR_nanosleep, sys_nanosleep), // 162
GENX_(__NR_mremap, sys_mremap), // 163
- LINX_(__NR_setresuid, sys_setresuid16), // 164
-
- LINXY(__NR_getresuid, sys_getresuid16), // 165
- // (__NR_vm86, sys_vm86), // 166 x86/Linux-only
+//zz LINX_(__NR_setresuid, sys_setresuid16), // 164
+//zz
+//zz LINXY(__NR_getresuid, sys_getresuid16), // 165
+//zz // (__NR_vm86, sys_vm86), // 166 x86/Linux-only
GENX_(__NR_query_module, sys_ni_syscall), // 167
GENXY(__NR_poll, sys_poll), // 168
- // (__NR_nfsservctl, sys_nfsservctl), // 169 */Linux
-
- LINX_(__NR_setresgid, sys_setresgid16), // 170
- LINXY(__NR_getresgid, sys_getresgid16), // 171
- LINX_(__NR_prctl, sys_prctl), // 172
+//zz // (__NR_nfsservctl, sys_nfsservctl), // 169 */Linux
+//zz
+//zz LINX_(__NR_setresgid, sys_setresgid16), // 170
+//zz LINXY(__NR_getresgid, sys_getresgid16), // 171
+//zz LINX_(__NR_prctl, sys_prctl), // 172
PLAX_(__NR_rt_sigreturn, sys_rt_sigreturn), // 173 x86/Linux only?
GENXY(__NR_rt_sigaction, sys_rt_sigaction), // 174
GENXY(__NR_rt_sigprocmask, sys_rt_sigprocmask), // 175
- GENXY(__NR_rt_sigpending, sys_rt_sigpending), // 176
+//zz GENXY(__NR_rt_sigpending, sys_rt_sigpending), // 176
GENXY(__NR_rt_sigtimedwait, sys_rt_sigtimedwait),// 177
- GENXY(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo),// 178
+//zz GENXY(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo),// 178
GENX_(__NR_rt_sigsuspend, sys_rt_sigsuspend), // 179
-
- GENXY(__NR_pread64, sys_pread64), // 180
- GENX_(__NR_pwrite64, sys_pwrite64), // 181
- GENX_(__NR_chown, sys_chown16), // 182
+//zz
+//zz GENXY(__NR_pread64, sys_pread64), // 180
+//zz GENX_(__NR_pwrite64, sys_pwrite64), // 181
+//zz GENX_(__NR_chown, sys_chown16), // 182
GENXY(__NR_getcwd, sys_getcwd), // 183
- GENXY(__NR_capget, sys_capget), // 184
-
- GENX_(__NR_capset, sys_capset), // 185
+//zz GENXY(__NR_capget, sys_capget), // 184
+//zz
+//zz GENX_(__NR_capset, sys_capset), // 185
GENXY(__NR_sigaltstack, sys_sigaltstack), // 186
- LINXY(__NR_sendfile, sys_sendfile), // 187
- GENXY(__NR_getpmsg, sys_getpmsg), // 188
- GENX_(__NR_putpmsg, sys_putpmsg), // 189
+//zz LINXY(__NR_sendfile, sys_sendfile), // 187
+//zz GENXY(__NR_getpmsg, sys_getpmsg), // 188
+//zz GENX_(__NR_putpmsg, sys_putpmsg), // 189
// Nb: we treat vfork as fork
GENX_(__NR_vfork, sys_fork), // 190
GENXY(__NR_ugetrlimit, sys_getrlimit), // 191
GENXY(__NR_mmap2, sys_mmap2), // 192
- GENX_(__NR_truncate64, sys_truncate64), // 193
- GENX_(__NR_ftruncate64, sys_ftruncate64), // 194
-
- GENXY(__NR_stat64, sys_stat64), // 195
- GENXY(__NR_lstat64, sys_lstat64), // 196
- GENXY(__NR_fstat64, sys_fstat64), // 197
- GENX_(__NR_lchown32, sys_lchown), // 198
+//zz GENX_(__NR_truncate64, sys_truncate64), // 193
+//zz GENX_(__NR_ftruncate64, sys_ftruncate64), // 194
+//zz
+ PLAXY(__NR_stat64, sys_stat64), // 195
+ PLAXY(__NR_lstat64, sys_lstat64), // 196
+ PLAXY(__NR_fstat64, sys_fstat64), // 197
+//zz GENX_(__NR_lchown32, sys_lchown), // 198
GENX_(__NR_getuid32, sys_getuid), // 199
-
- GENX_(__NR_getgid32, sys_getgid), // 200
+//zz
+//zz GENX_(__NR_getgid32, sys_getgid), // 200
GENX_(__NR_geteuid32, sys_geteuid), // 201
- GENX_(__NR_getegid32, sys_getegid), // 202
- GENX_(__NR_setreuid32, sys_setreuid), // 203
- GENX_(__NR_setregid32, sys_setregid), // 204
-
- GENXY(__NR_getgroups32, sys_getgroups), // 205
- GENX_(__NR_setgroups32, sys_setgroups), // 206
- GENX_(__NR_fchown32, sys_fchown), // 207
- LINX_(__NR_setresuid32, sys_setresuid), // 208
- LINXY(__NR_getresuid32, sys_getresuid), // 209
-
- LINX_(__NR_setresgid32, sys_setresgid), // 210
- LINXY(__NR_getresgid32, sys_getresgid), // 211
- GENX_(__NR_chown32, sys_chown), // 212
- GENX_(__NR_setuid32, sys_setuid), // 213
- GENX_(__NR_setgid32, sys_setgid), // 214
-
- LINX_(__NR_setfsuid32, sys_setfsuid), // 215
- LINX_(__NR_setfsgid32, sys_setfsgid), // 216
- // (__NR_pivot_root, sys_pivot_root), // 217 */Linux
- GENXY(__NR_mincore, sys_mincore), // 218
+//zz GENX_(__NR_getegid32, sys_getegid), // 202
+//zz GENX_(__NR_setreuid32, sys_setreuid), // 203
+//zz GENX_(__NR_setregid32, sys_setregid), // 204
+//zz
+//zz GENXY(__NR_getgroups32, sys_getgroups), // 205
+//zz GENX_(__NR_setgroups32, sys_setgroups), // 206
+//zz GENX_(__NR_fchown32, sys_fchown), // 207
+//zz LINX_(__NR_setresuid32, sys_setresuid), // 208
+//zz LINXY(__NR_getresuid32, sys_getresuid), // 209
+//zz
+//zz LINX_(__NR_setresgid32, sys_setresgid), // 210
+//zz LINXY(__NR_getresgid32, sys_getresgid), // 211
+//zz GENX_(__NR_chown32, sys_chown), // 212
+//zz GENX_(__NR_setuid32, sys_setuid), // 213
+//zz GENX_(__NR_setgid32, sys_setgid), // 214
+//zz
+//zz LINX_(__NR_setfsuid32, sys_setfsuid), // 215
+//zz LINX_(__NR_setfsgid32, sys_setfsgid), // 216
+//zz // (__NR_pivot_root, sys_pivot_root), // 217 */Linux
+//zz GENXY(__NR_mincore, sys_mincore), // 218
GENX_(__NR_madvise, sys_madvise), // 219
GENXY(__NR_getdents64, sys_getdents64), // 220
GENXY(__NR_fcntl64, sys_fcntl64), // 221
GENX_(222, sys_ni_syscall), // 222
GENX_(223, sys_ni_syscall), // 223
- LINX_(__NR_gettid, sys_gettid), // 224
-
- // (__NR_readahead, sys_readahead), // 225 */(Linux?)
- GENX_(__NR_setxattr, sys_setxattr), // 226
- GENX_(__NR_lsetxattr, sys_lsetxattr), // 227
- GENX_(__NR_fsetxattr, sys_fsetxattr), // 228
+//zz LINX_(__NR_gettid, sys_gettid), // 224
+//zz
+//zz // (__NR_readahead, sys_readahead), // 225 */(Linux?)
+//zz GENX_(__NR_setxattr, sys_setxattr), // 226
+//zz GENX_(__NR_lsetxattr, sys_lsetxattr), // 227
+//zz GENX_(__NR_fsetxattr, sys_fsetxattr), // 228
GENXY(__NR_getxattr, sys_getxattr), // 229
-
- GENXY(__NR_lgetxattr, sys_lgetxattr), // 230
- GENXY(__NR_fgetxattr, sys_fgetxattr), // 231
- GENXY(__NR_listxattr, sys_listxattr), // 232
- GENXY(__NR_llistxattr, sys_llistxattr), // 233
- GENXY(__NR_flistxattr, sys_flistxattr), // 234
-
- GENX_(__NR_removexattr, sys_removexattr), // 235
- GENX_(__NR_lremovexattr, sys_lremovexattr), // 236
- GENX_(__NR_fremovexattr, sys_fremovexattr), // 237
- LINX_(__NR_tkill, sys_tkill), // 238 */Linux
- LINXY(__NR_sendfile64, sys_sendfile64), // 239
-
- LINXY(__NR_futex, sys_futex), // 240
- GENX_(__NR_sched_setaffinity, sys_sched_setaffinity), // 241
- GENXY(__NR_sched_getaffinity, sys_sched_getaffinity), // 242
- PLAX_(__NR_set_thread_area, sys_set_thread_area), // 243
- PLAX_(__NR_get_thread_area, sys_get_thread_area), // 244
-
- LINX_(__NR_io_setup, sys_io_setup), // 245
- LINX_(__NR_io_destroy, sys_io_destroy), // 246
- LINXY(__NR_io_getevents, sys_io_getevents), // 247
- LINX_(__NR_io_submit, sys_io_submit), // 248
- LINXY(__NR_io_cancel, sys_io_cancel), // 249
-
- LINX_(__NR_fadvise64, sys_fadvise64), // 250 */(Linux?)
+//zz
+//zz GENXY(__NR_lgetxattr, sys_lgetxattr), // 230
+//zz GENXY(__NR_fgetxattr, sys_fgetxattr), // 231
+//zz GENXY(__NR_listxattr, sys_listxattr), // 232
+//zz GENXY(__NR_llistxattr, sys_llistxattr), // 233
+//zz GENXY(__NR_flistxattr, sys_flistxattr), // 234
+//zz
+//zz GENX_(__NR_removexattr, sys_removexattr), // 235
+//zz GENX_(__NR_lremovexattr, sys_lremovexattr), // 236
+//zz GENX_(__NR_fremovexattr, sys_fremovexattr), // 237
+//zz LINX_(__NR_tkill, sys_tkill), // 238 */Linux
+//zz LINXY(__NR_sendfile64, sys_sendfile64), // 239
+//zz
+//zz LINXY(__NR_futex, sys_futex), // 240
+//zz GENX_(__NR_sched_setaffinity, sys_sched_setaffinity), // 241
+//zz GENXY(__NR_sched_getaffinity, sys_sched_getaffinity), // 242
+//zz PLAX_(__NR_set_thread_area, sys_set_thread_area), // 243
+//zz PLAX_(__NR_get_thread_area, sys_get_thread_area), // 244
+//zz
+//zz LINX_(__NR_io_setup, sys_io_setup), // 245
+//zz LINX_(__NR_io_destroy, sys_io_destroy), // 246
+//zz LINXY(__NR_io_getevents, sys_io_getevents), // 247
+//zz LINX_(__NR_io_submit, sys_io_submit), // 248
+//zz LINXY(__NR_io_cancel, sys_io_cancel), // 249
+//zz
+//zz LINX_(__NR_fadvise64, sys_fadvise64), // 250 */(Linux?)
GENX_(251, sys_ni_syscall), // 251
LINX_(__NR_exit_group, sys_exit_group), // 252
- GENXY(__NR_lookup_dcookie, sys_lookup_dcookie), // 253
- LINXY(__NR_epoll_create, sys_epoll_create), // 254
-
- LINX_(__NR_epoll_ctl, sys_epoll_ctl), // 255
- LINXY(__NR_epoll_wait, sys_epoll_wait), // 256
- // (__NR_remap_file_pages, sys_remap_file_pages), // 257 */Linux
- GENX_(__NR_set_tid_address, sys_set_tid_address), // 258
- GENXY(__NR_timer_create, sys_timer_create), // 259
-
- GENXY(__NR_timer_settime, sys_timer_settime), // (timer_create+1)
- GENXY(__NR_timer_gettime, sys_timer_gettime), // (timer_create+2)
- GENX_(__NR_timer_getoverrun, sys_timer_getoverrun),//(timer_create+3)
- GENX_(__NR_timer_delete, sys_timer_delete), // (timer_create+4)
- GENX_(__NR_clock_settime, sys_clock_settime), // (timer_create+5)
-
+//zz GENXY(__NR_lookup_dcookie, sys_lookup_dcookie), // 253
+//zz LINXY(__NR_epoll_create, sys_epoll_create), // 254
+//zz
+//zz LINX_(__NR_epoll_ctl, sys_epoll_ctl), // 255
+//zz LINXY(__NR_epoll_wait, sys_epoll_wait), // 256
+//zz // (__NR_remap_file_pages, sys_remap_file_pages), // 257 */Linux
+//zz GENX_(__NR_set_tid_address, sys_set_tid_address), // 258
+//zz GENXY(__NR_timer_create, sys_timer_create), // 259
+//zz
+//zz GENXY(__NR_timer_settime, sys_timer_settime), // (timer_create+1)
+//zz GENXY(__NR_timer_gettime, sys_timer_gettime), // (timer_create+2)
+//zz GENX_(__NR_timer_getoverrun, sys_timer_getoverrun),//(timer_create+3)
+//zz GENX_(__NR_timer_delete, sys_timer_delete), // (timer_create+4)
+//zz GENX_(__NR_clock_settime, sys_clock_settime), // (timer_create+5)
+//zz
GENXY(__NR_clock_gettime, sys_clock_gettime), // (timer_create+6)
- GENXY(__NR_clock_getres, sys_clock_getres), // (timer_create+7)
- // (__NR_clock_nanosleep, sys_clock_nanosleep),// (timer_create+8) */*
- GENXY(__NR_statfs64, sys_statfs64), // 268
- GENXY(__NR_fstatfs64, sys_fstatfs64), // 269
-
- LINX_(__NR_tgkill, sys_tgkill), // 270 */Linux
- GENX_(__NR_utimes, sys_utimes), // 271
- LINX_(__NR_fadvise64_64, sys_fadvise64_64), // 272 */(Linux?)
+//zz GENXY(__NR_clock_getres, sys_clock_getres), // (timer_create+7)
+//zz // (__NR_clock_nanosleep, sys_clock_nanosleep),// (timer_create+8) */*
+//zz GENXY(__NR_statfs64, sys_statfs64), // 268
+//zz GENXY(__NR_fstatfs64, sys_fstatfs64), // 269
+//zz
+//zz LINX_(__NR_tgkill, sys_tgkill), // 270 */Linux
+//zz GENX_(__NR_utimes, sys_utimes), // 271
+//zz LINX_(__NR_fadvise64_64, sys_fadvise64_64), // 272 */(Linux?)
GENX_(__NR_vserver, sys_ni_syscall), // 273
- // (__NR_mbind, sys_mbind), // 274 ?/?
-
- // (__NR_get_mempolicy, sys_get_mempolicy), // 275 ?/?
- // (__NR_set_mempolicy, sys_set_mempolicy), // 276 ?/?
- GENXY(__NR_mq_open, sys_mq_open), // 277
- GENX_(__NR_mq_unlink, sys_mq_unlink), // (mq_open+1)
- GENX_(__NR_mq_timedsend, sys_mq_timedsend), // (mq_open+2)
-
- GENXY(__NR_mq_timedreceive, sys_mq_timedreceive),// (mq_open+3)
- GENX_(__NR_mq_notify, sys_mq_notify), // (mq_open+4)
- GENXY(__NR_mq_getsetattr, sys_mq_getsetattr), // (mq_open+5)
+//zz // (__NR_mbind, sys_mbind), // 274 ?/?
+//zz
+//zz // (__NR_get_mempolicy, sys_get_mempolicy), // 275 ?/?
+//zz // (__NR_set_mempolicy, sys_set_mempolicy), // 276 ?/?
+//zz GENXY(__NR_mq_open, sys_mq_open), // 277
+//zz GENX_(__NR_mq_unlink, sys_mq_unlink), // (mq_open+1)
+//zz GENX_(__NR_mq_timedsend, sys_mq_timedsend), // (mq_open+2)
+//zz
+//zz GENXY(__NR_mq_timedreceive, sys_mq_timedreceive),// (mq_open+3)
+//zz GENX_(__NR_mq_notify, sys_mq_notify), // (mq_open+4)
+//zz GENXY(__NR_mq_getsetattr, sys_mq_getsetattr), // (mq_open+5)
GENX_(__NR_sys_kexec_load, sys_ni_syscall), // 283
};
-const UInt VGA_(syscall_table_size) =
- sizeof(VGA_(syscall_table)) / sizeof(VGA_(syscall_table)[0]);
+const UInt VGP_(syscall_table_size) =
+ sizeof(VGP_(syscall_table)) / sizeof(VGP_(syscall_table)[0]);
/*--------------------------------------------------------------------*/
/*--- end ---*/
diff --git a/coregrind/m_tooliface.c b/coregrind/m_tooliface.c
index dc06c8518..962b45ccd 100644
--- a/coregrind/m_tooliface.c
+++ b/coregrind/m_tooliface.c
@@ -216,7 +216,7 @@ void VG_(needs_client_requests)(
void VG_(needs_syscall_wrapper)(
void(*pre) (ThreadId, UInt),
- void(*post)(ThreadId, UInt, Int res)
+ void(*post)(ThreadId, UInt, SysRes res)
)
{
VG_(needs).syscall_wrapper = True;
diff --git a/coregrind/pub_core_libcbase.h b/coregrind/pub_core_libcbase.h
index 5c20e8b79..e65c6653c 100644
--- a/coregrind/pub_core_libcbase.h
+++ b/coregrind/pub_core_libcbase.h
@@ -39,6 +39,74 @@
#include "pub_tool_libcbase.h"
+/* ---------------------------------------------------------------------
+ Fundamental functions for doing syscalls on this platform.
+ ------------------------------------------------------------------ */
+
+/* Do a syscall on this platform, with 6 args, and return the result
+ in canonical format in a SysRes value. */
+
+extern SysRes VG_(do_syscall) ( UWord sysno,
+ UWord, UWord, UWord,
+ UWord, UWord, UWord );
+
+/* Macros make life easier. */
+
+#define vgPlain_do_syscall0(s) VG_(do_syscall)((s),0,0,0,0,0,0)
+#define vgPlain_do_syscall1(s,a) VG_(do_syscall)((s),(a),0,0,0,0,0)
+#define vgPlain_do_syscall2(s,a,b) VG_(do_syscall)((s),(a),(b),0,0,0,0)
+#define vgPlain_do_syscall3(s,a,b,c) VG_(do_syscall)((s),(a),(b),(c),0,0,0)
+#define vgPlain_do_syscall4(s,a,b,c,d) VG_(do_syscall)((s),(a),(b),\
+ (c),(d),0,0)
+#define vgPlain_do_syscall5(s,a,b,c,d,e) VG_(do_syscall)((s),(a),(b),\
+ (c),(d),(e),0)
+#define vgPlain_do_syscall6(s,a,b,c,d,e,f) VG_(do_syscall)((s),(a),(b),\
+ (c),(d),(e),(f))
+
+
+/* Build SysRes values -- occasionally useful. */
+
+static inline SysRes VG_(mk_SysRes_Error) ( UWord err ) {
+ SysRes r = { err, True };
+ return r;
+}
+
+static inline SysRes VG_(mk_SysRes_Success) ( UWord err ) {
+ SysRes r = { err, False };
+ return r;
+}
+
+
+/* This is absolutely the wrong place for these, but I can't figure
+ out anywhere else for them to go. */
+
+/* Make a SysRes value from an %eax syscall return value on
+ x86-linux.
+
+ From:
+ http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/sysdeps/unix/sysv/
+ linux/i386/sysdep.h?
+ rev=1.28&content-type=text/x-cvsweb-markup&cvsroot=glibc
+
+ Linux uses a negative return value to indicate syscall errors,
+ unlike most Unices, which use the condition codes' carry flag.
+
+ Since version 2.1 the return value of a system call might be
+ negative even if the call succeeded. E.g., the 'lseek' system call
+ might return a large offset. Therefore we must not anymore test
+ for < 0, but test for a real error by making sure the value in %eax
+ is a real error number. Linus said he will make sure the no
+ syscall returns a value in -1 .. -4095 as a valid result so we can
+ safely test with -4095.
+*/
+static inline SysRes VG_(mk_SysRes_x86_linux) ( Int eax ) {
+ SysRes res;
+ res.isError = eax >= -4095 && eax <= -1;
+ res.val = res.isError ? -eax : eax;
+ return res;
+}
+
+
#endif // __PUB_CORE_LIBCBASE_H
/*--------------------------------------------------------------------*/
diff --git a/coregrind/pub_core_scheduler.h b/coregrind/pub_core_scheduler.h
index db49232a7..ddc785ff2 100644
--- a/coregrind/pub_core_scheduler.h
+++ b/coregrind/pub_core_scheduler.h
@@ -138,10 +138,6 @@ typedef struct {
be rare. */
struct SigQueue *sig_queue;
- /* Syscall the Thread is currently running; -1 if none. Should only
- be set while Thread is in VgTs_WaitSys. */
- Int syscallno;
-
/* Client stacks. When a thread slot is freed, we don't deallocate its
stack; we just leave it lying around for the next use of the
slot. If the next use of the slot requires a larger stack,
diff --git a/coregrind/pub_core_signals.h b/coregrind/pub_core_signals.h
index ac640541c..444694d7f 100644
--- a/coregrind/pub_core_signals.h
+++ b/coregrind/pub_core_signals.h
@@ -40,18 +40,19 @@ extern Int VG_(max_signal);
extern void VG_(sigstartup_actions) ( void );
-/* Poll a thread's set of pending signals, and update the Thread's context to deliver one */
+/* Poll a thread's set of pending signals, and update the Thread's
+ context to deliver one (viz, create signal frames if needed) */
extern void VG_(poll_signals) ( ThreadId );
/* Fake system calls for signal handling. */
-extern Int VG_(do_sys_sigaltstack) ( ThreadId tid, vki_stack_t* ss,
- vki_stack_t* oss );
-extern Int VG_(do_sys_sigaction) ( Int signo,
- const struct vki_sigaction *new_act,
- struct vki_sigaction *old_act );
-extern Int VG_(do_sys_sigprocmask) ( ThreadId tid, Int how,
- vki_sigset_t* set,
- vki_sigset_t* oldset );
+extern SysRes VG_(do_sys_sigaltstack) ( ThreadId tid, vki_stack_t* ss,
+ vki_stack_t* oss );
+extern SysRes VG_(do_sys_sigaction) ( Int signo,
+ const struct vki_sigaction *new_act,
+ struct vki_sigaction *old_act );
+extern SysRes VG_(do_sys_sigprocmask) ( ThreadId tid, Int how,
+ vki_sigset_t* set,
+ vki_sigset_t* oldset );
extern void VG_(clear_out_queued_signals)
( ThreadId tid, /* OUT */ vki_sigset_t* saved_mask );
diff --git a/coregrind/pub_core_syscalls.h b/coregrind/pub_core_syscalls.h
index fed4146d5..e54dc2ca9 100644
--- a/coregrind/pub_core_syscalls.h
+++ b/coregrind/pub_core_syscalls.h
@@ -43,23 +43,21 @@ extern void VG_(client_syscall) ( ThreadId tid );
extern void VG_(post_syscall) ( ThreadId tid );
-// Fix up the thread's state because a syscall may have been
-// interrupted with a signal. Returns True if the syscall completed
-// (either interrupted or finished normally), or False if it was
-// restarted (or the signal didn't actually interrupt a syscall).
-extern void VGP_(interrupted_syscall)(ThreadId tid,
- Word eip, UWord sysnum, UWord sysret,
- Bool restart);
+/* Clear this module's private state for thread 'tid' */
+extern void VG_(clear_syscallInfo) ( Int tid );
+
+// Fix up a thread's state when syscall is interrupted by a signal.
+extern void VG_(fixup_guest_state_after_syscall_interrupted)(
+ ThreadId tid,
+ Addr ip,
+ UWord sysnum,
+ SysRes sysret,
+ Bool restart
+ );
// Release resources held by this thread
extern void VGP_(cleanup_thread) ( ThreadArchState* );
-extern Bool VG_(is_kerror) ( Word res );
-
-/* Internal atfork handlers */
-typedef void (*vg_atfork_t)(ThreadId);
-extern void VG_(atfork)(vg_atfork_t pre, vg_atfork_t parent, vg_atfork_t child);
-
/* fd leakage calls. */
extern void VG_(init_preopened_fds) ( void );
extern void VG_(show_open_fds) ( void );
diff --git a/coregrind/pub_core_tooliface.h b/coregrind/pub_core_tooliface.h
index fbd97709a..b779327e6 100644
--- a/coregrind/pub_core_tooliface.h
+++ b/coregrind/pub_core_tooliface.h
@@ -135,7 +135,7 @@ typedef struct {
// VG_(needs).syscall_wrapper
void (*tool_pre_syscall) (ThreadId, UInt);
- void (*tool_post_syscall)(ThreadId, UInt, Int);
+ void (*tool_post_syscall)(ThreadId, UInt, SysRes);
// VG_(needs).sanity_checks
Bool (*tool_cheap_sanity_check)(void);
diff --git a/coregrind/vg_mylibc.c b/coregrind/vg_mylibc.c
index 03effb9c5..6c0fe19a8 100644
--- a/coregrind/vg_mylibc.c
+++ b/coregrind/vg_mylibc.c
@@ -36,6 +36,7 @@
#include "pub_core_libcbase.h"
#include "pub_core_libcassert.h"
#include "pub_core_libcprint.h"
+#include "pub_core_libcfile.h"
#include "pub_core_main.h"
#include "pub_core_options.h"
#include "pub_core_stacktrace.h"
@@ -159,77 +160,76 @@ void VG_(sigdelset_from_set)( vki_sigset_t* dst, vki_sigset_t* src )
*/
Int VG_(sigprocmask)( Int how, const vki_sigset_t* set, vki_sigset_t* oldset)
{
- Int res = VG_(do_syscall4)(__NR_rt_sigprocmask,
- how, (UWord)set, (UWord)oldset,
- _VKI_NSIG_WORDS * sizeof(UWord));
- return VG_(is_kerror)(res) ? -1 : 0;
+ SysRes res = VG_(do_syscall4)(__NR_rt_sigprocmask,
+ how, (UWord)set, (UWord)oldset,
+ _VKI_NSIG_WORDS * sizeof(UWord));
+ return res.isError ? -1 : 0;
}
Int VG_(sigaction) ( Int signum, const struct vki_sigaction* act,
struct vki_sigaction* oldact)
{
- Int res = VG_(do_syscall4)(__NR_rt_sigaction,
- signum, (UWord)act, (UWord)oldact,
- _VKI_NSIG_WORDS * sizeof(UWord));
- /* VG_(printf)("res = %d\n",res); */
- return VG_(is_kerror)(res) ? -1 : 0;
+ SysRes res = VG_(do_syscall4)(__NR_rt_sigaction,
+ signum, (UWord)act, (UWord)oldact,
+ _VKI_NSIG_WORDS * sizeof(UWord));
+ return res.isError ? -1 : 0;
}
Int VG_(sigaltstack)( const vki_stack_t* ss, vki_stack_t* oss )
{
- Int res = VG_(do_syscall2)(__NR_sigaltstack, (UWord)ss, (UWord)oss);
- return VG_(is_kerror)(res) ? -1 : 0;
+ SysRes res = VG_(do_syscall2)(__NR_sigaltstack, (UWord)ss, (UWord)oss);
+ return res.isError ? -1 : 0;
}
Int VG_(sigtimedwait)( const vki_sigset_t *set, vki_siginfo_t *info,
const struct vki_timespec *timeout )
{
- Int res = VG_(do_syscall4)(__NR_rt_sigtimedwait, (UWord)set, (UWord)info,
- (UWord)timeout, sizeof(*set));
-
- return res;
+ SysRes res = VG_(do_syscall4)(__NR_rt_sigtimedwait, (UWord)set, (UWord)info,
+ (UWord)timeout, sizeof(*set));
+ return res.isError ? -1 : res.val;
}
Int VG_(signal)(Int signum, void (*sighandler)(Int))
{
- Int res;
+ SysRes res;
+ Int n;
struct vki_sigaction sa;
sa.ksa_handler = sighandler;
sa.sa_flags = VKI_SA_ONSTACK | VKI_SA_RESTART;
sa.sa_restorer = NULL;
- res = VG_(sigemptyset)( &sa.sa_mask );
- vg_assert(res == 0);
+ n = VG_(sigemptyset)( &sa.sa_mask );
+ vg_assert(n == 0);
res = VG_(do_syscall4)(__NR_rt_sigaction, signum, (UWord)&sa, (UWord)NULL,
- _VKI_NSIG_WORDS * sizeof(UWord));
- return VG_(is_kerror)(res) ? -1 : 0;
+ _VKI_NSIG_WORDS * sizeof(UWord));
+ return res.isError ? -1 : 0;
}
Int VG_(kill)( Int pid, Int signo )
{
- Int res = VG_(do_syscall2)(__NR_kill, pid, signo);
- return VG_(is_kerror)(res) ? -1 : 0;
+ SysRes res = VG_(do_syscall2)(__NR_kill, pid, signo);
+ return res.isError ? -1 : 0;
}
Int VG_(tkill)( ThreadId tid, Int signo )
{
- Int ret = -VKI_ENOSYS;
+ SysRes res = VG_(mk_SysRes_Error)(VKI_ENOSYS);
#if 0
/* This isn't right because the client may create a process
structure with multiple thread groups */
- ret = VG_(do_syscall)(__NR_tgkill, VG_(getpid)(), tid, signo);
+ res = VG_(do_syscall)(__NR_tgkill, VG_(getpid)(), tid, signo);
#endif
- ret = VG_(do_syscall2)(__NR_tkill, tid, signo);
+ res = VG_(do_syscall2)(__NR_tkill, tid, signo);
- if (ret == -VKI_ENOSYS)
- ret = VG_(do_syscall2)(__NR_kill, tid, signo);
+ if (res.isError && res.val == VKI_ENOSYS)
+ res = VG_(do_syscall2)(__NR_kill, tid, signo);
- return VG_(is_kerror)(ret) ? -1 : 0;
+ return res.isError ? -1 : 0;
}
Int VG_(sigpending) ( vki_sigset_t* set )
@@ -241,27 +241,23 @@ Int VG_(sigpending) ( vki_sigset_t* set )
#ifdef __amd64__
I_die_here;
#else
- Int res = VG_(do_syscall1)(__NR_sigpending, (UWord)set);
- return VG_(is_kerror)(res) ? -1 : 0;
+ SysRes res = VG_(do_syscall1)(__NR_sigpending, (UWord)set);
+ return res.isError ? -1 : 0;
#endif
}
Int VG_(waitpid)(Int pid, Int *status, Int options)
{
- Int ret = VG_(do_syscall4)(__NR_wait4, pid, (UWord)status, options, 0);
-
- return VG_(is_kerror)(ret) ? -1 : ret;
+ SysRes res = VG_(do_syscall4)(__NR_wait4, pid, (UWord)status, options, 0);
+ return res.isError ? -1 : res.val;
}
Int VG_(gettid)(void)
{
- Int ret;
-
- ret = VG_(do_syscall0)(__NR_gettid);
+ SysRes res = VG_(do_syscall0)(__NR_gettid);
- if (ret == -VKI_ENOSYS) {
- Char pid[16];
-
+ if (res.isError && res.val == VKI_ENOSYS) {
+ Char pid[16];
/*
* The gettid system call does not exist. The obvious assumption
* to make at this point would be that we are running on an older
@@ -275,15 +271,16 @@ Int VG_(gettid)(void)
* So instead of calling getpid here we use readlink to see where
* the /proc/self link is pointing...
*/
- if ((ret = VG_(do_syscall3)(__NR_readlink, (UWord)"/proc/self",
- (UWord)pid, sizeof(pid))) >= 0)
- {
- pid[ret] = '\0';
- ret = VG_(atoll)(pid);
+
+ 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);
}
}
- return ret;
+ return res.val;
}
@@ -292,11 +289,11 @@ Int VG_(gettid)(void)
mmap/munmap, exit, fcntl
------------------------------------------------------------------ */
-void* VG_(mmap_native)(void *start, SizeT length, UInt prot, UInt flags,
- UInt fd, OffT offset)
+SysRes VG_(mmap_native)(void *start, SizeT length, UInt prot, UInt flags,
+ UInt fd, OffT offset)
{
- UWord ret;
-#if defined(VGP_x86_linux)
+ SysRes res;
+# if defined(VGP_x86_linux)
{
UWord args[6];
args[0] = (UWord)start;
@@ -305,22 +302,22 @@ void* VG_(mmap_native)(void *start, SizeT length, UInt prot, UInt flags,
args[3] = flags;
args[4] = fd;
args[5] = offset;
- ret = VG_(do_syscall1)(__NR_mmap, (UWord)args );
+ res = VG_(do_syscall1)(__NR_mmap, (UWord)args );
}
-#elif defined(VGP_amd64_linux)
- ret = VG_(do_syscall6)(__NR_mmap, (UWord)start, length,
+# elif defined(VGP_amd64_linux)
+ res = VG_(do_syscall6)(__NR_mmap, (UWord)start, length,
prot, flags, fd, offset);
-#else
-# error Unknown platform
-#endif
- return VG_(is_kerror)(ret) ? (void*)-1 : (void*)ret;
+# else
+# error Unknown platform
+# endif
+ return res;
}
/* Returns -1 on failure. */
void* VG_(mmap)( void* start, SizeT length,
UInt prot, UInt flags, UInt sf_flags, UInt fd, OffT offset)
{
- Addr res;
+ SysRes res;
if (!(flags & VKI_MAP_FIXED)) {
start = (void *)VG_(find_map_space)((Addr)start, length, !!(flags & VKI_MAP_CLIENT));
@@ -330,16 +327,18 @@ void* VG_(mmap)( void* start, SizeT length,
if (start == 0)
return (void *)-1;
- res = (Addr)VG_(mmap_native)(start, length, prot,
- flags & ~(VKI_MAP_NOSYMS | VKI_MAP_CLIENT),
- fd, offset);
+ res = VG_(mmap_native)(start, length, prot,
+ flags & ~(VKI_MAP_NOSYMS | VKI_MAP_CLIENT),
+ fd, offset);
// Check it ended up in the right place.
- if (res != (Addr)-1) {
+ if (!res.isError) {
if (flags & VKI_MAP_CLIENT) {
- vg_assert(VG_(client_base) <= res && res+length <= VG_(client_end));
+ vg_assert(VG_(client_base) <= res.val
+ && res.val+length <= VG_(client_end));
} else {
- vg_assert(VG_(valgrind_base) <= res && res+length-1 <= VG_(valgrind_last));
+ vg_assert(VG_(valgrind_base) <= res.val
+ && res.val+length-1 <= VG_(valgrind_last));
}
sf_flags |= SF_MMAP;
@@ -349,16 +348,16 @@ void* VG_(mmap)( void* start, SizeT length,
if (!(flags & VKI_MAP_CLIENT)) sf_flags |= SF_VALGRIND;
if ( flags & VKI_MAP_NOSYMS) sf_flags |= SF_NOSYMS;
- VG_(map_fd_segment)(res, length, prot, sf_flags, fd, offset, NULL);
+ VG_(map_fd_segment)(res.val, length, prot, sf_flags, fd, offset, NULL);
}
- return (void*)res;
+ return res.isError ? (void*)-1 : (void*)res.val;
}
static Int munmap_native(void *start, SizeT length)
{
- Int res = VG_(do_syscall2)(__NR_munmap, (UWord)start, length );
- return VG_(is_kerror)(res) ? -1 : 0;
+ SysRes res = VG_(do_syscall2)(__NR_munmap, (UWord)start, length );
+ return res.isError ? -1 : 0;
}
/* Returns -1 on failure. */
@@ -372,8 +371,8 @@ Int VG_(munmap)( void* start, SizeT length )
Int VG_(mprotect_native)( void *start, SizeT length, UInt prot )
{
- Int res = VG_(do_syscall3)(__NR_mprotect, (UWord)start, length, prot );
- return VG_(is_kerror)(res) ? -1 : 0;
+ SysRes res = VG_(do_syscall3)(__NR_mprotect, (UWord)start, length, prot );
+ return res.isError ? -1 : 0;
}
Int VG_(mprotect)( void *start, SizeT length, UInt prot )
@@ -398,15 +397,15 @@ void VG_(exit)( Int status )
/* Returns -1 on error. */
Int VG_(fcntl) ( Int fd, Int cmd, Int arg )
{
- Int res = VG_(do_syscall3)(__NR_fcntl, fd, cmd, arg);
- return VG_(is_kerror)(res) ? -1 : res;
+ SysRes res = VG_(do_syscall3)(__NR_fcntl, fd, cmd, arg);
+ return res.isError ? -1 : res.val;
}
Int VG_(poll)( struct vki_pollfd *ufds, UInt nfds, Int timeout)
{
- Int res = VG_(do_syscall3)(__NR_poll, (UWord)ufds, nfds, timeout);
-
- return res;
+ SysRes res = VG_(do_syscall3)(__NR_poll, (UWord)ufds, nfds, timeout);
+ /* ASSUMES SYSCALL ALWAYS SUCCEEDS */
+ return res.val;
}
@@ -543,56 +542,49 @@ Char *VG_(getenv)(Char *varname)
/* Support for getrlimit. */
Int VG_(getrlimit) (Int resource, struct vki_rlimit *rlim)
{
- Int res = -VKI_ENOSYS;
+ SysRes res = VG_(mk_SysRes_Error)(VKI_ENOSYS);
/* res = getrlimit( resource, rlim ); */
# ifdef __NR_ugetrlimit
res = VG_(do_syscall2)(__NR_ugetrlimit, resource, (UWord)rlim);
# endif
- if (res == -VKI_ENOSYS)
+ if (res.isError && res.val == VKI_ENOSYS)
res = VG_(do_syscall2)(__NR_getrlimit, resource, (UWord)rlim);
- if (VG_(is_kerror)(res)) res = -1;
- return res;
+ return res.isError ? -1 : res.val;
}
/* Support for setrlimit. */
Int VG_(setrlimit) (Int resource, const struct vki_rlimit *rlim)
{
- Int res;
+ SysRes res;
/* res = setrlimit( resource, rlim ); */
res = VG_(do_syscall2)(__NR_setrlimit, resource, (UWord)rlim);
- if (VG_(is_kerror)(res)) res = -1;
- return res;
+ return res.isError ? -1 : res.val;
}
-
/* You'd be amazed how many places need to know the current pid. */
Int VG_(getpid) ( void )
{
- Int res;
- /* res = getpid(); */
- res = VG_(do_syscall0)(__NR_getpid);
- return res;
+ /* ASSUMES SYSCALL ALWAYS SUCCEEDS */
+ return VG_(do_syscall0)(__NR_getpid) . val;
}
Int VG_(getpgrp) ( void )
{
- Int res;
- /* res = getpgid(); */
- res = VG_(do_syscall0)(__NR_getpgrp);
- return res;
+ /* ASSUMES SYSCALL ALWAYS SUCCEEDS */
+ return VG_(do_syscall0)(__NR_getpgrp) . val;
}
Int VG_(getppid) ( void )
{
- Int res;
- res = VG_(do_syscall0)(__NR_getppid);
- return res;
+ /* ASSUMES SYSCALL ALWAYS SUCCEEDS */
+ return VG_(do_syscall0)(__NR_getppid) . val;
}
Int VG_(setpgid) ( Int pid, Int pgrp )
{
- return VG_(do_syscall2)(__NR_setpgid, pid, pgrp);
+ /* ASSUMES SYSCALL ALWAYS SUCCEEDS */
+ return VG_(do_syscall2)(__NR_setpgid, pid, pgrp) . val;
}
/* Walk through a colon-separated environment variable, and remove the
@@ -695,12 +687,14 @@ void VG_(env_remove_valgrind_env_stuff)(Char** envp)
child! */
Int VG_(system) ( Char* cmd )
{
- Int pid, res;
+ Int pid;
+ SysRes res;
if (cmd == NULL)
return 1;
- pid = VG_(do_syscall0)(__NR_fork);
- if (VG_(is_kerror)(pid))
+ res = VG_(do_syscall0)(__NR_fork);
+ if (res.isError)
return -1;
+ pid = res.val;
if (pid == 0) {
/* child */
static Char** envp = NULL;
@@ -724,12 +718,8 @@ Int VG_(system) ( Char* cmd )
VG_(exit)(1);
} else {
/* parent */
- res = VG_(waitpid)(pid, NULL, 0);
- if (VG_(is_kerror)(res)) {
- return -1;
- } else {
- return 0;
- }
+ Int zzz = VG_(waitpid)(pid, NULL, 0);
+ return zzz == -1 ? -1 : 0;
}
}
@@ -742,8 +732,8 @@ UInt VG_(read_millisecond_timer) ( void )
{
static ULong base = 0;
struct vki_timeval tv_now;
- ULong now;
- Int res;
+ ULong now;
+ SysRes res;
res = VG_(do_syscall2)(__NR_gettimeofday, (UWord)&tv_now, (UWord)NULL);
@@ -758,7 +748,7 @@ UInt VG_(read_millisecond_timer) ( void )
void VG_(nanosleep)(struct vki_timespec *ts)
{
- VG_(do_syscall2)(__NR_nanosleep, (UWord)ts, (UWord)NULL);
+ (void)VG_(do_syscall2)(__NR_nanosleep, (UWord)ts, (UWord)NULL);
}
/* ---------------------------------------------------------------------
@@ -795,6 +785,75 @@ void* VG_(get_memory_from_mmap) ( SizeT nBytes, Char* who )
VG_(exit)(1);
}
+/* ---------------------------------------------------------------------
+ Misc stuff looking for a proper home
+ ------------------------------------------------------------------ */
+
+/* ---------------------------------------------------------------------
+ A simple atfork() facility for Valgrind's internal use
+ ------------------------------------------------------------------ */
+
+struct atfork {
+ vg_atfork_t pre;
+ vg_atfork_t parent;
+ vg_atfork_t child;
+};
+
+#define VG_MAX_ATFORK 10
+
+static struct atfork atforks[VG_MAX_ATFORK];
+static Int n_atfork;
+
+void VG_(atfork)(vg_atfork_t pre, vg_atfork_t parent, vg_atfork_t child)
+{
+ Int i;
+
+ for(i = 0; i < n_atfork; i++) {
+ if (atforks[i].pre == pre &&
+ atforks[i].parent == parent &&
+ atforks[i].child == child)
+ return;
+ }
+
+ if (n_atfork >= VG_MAX_ATFORK)
+ VG_(core_panic)("Too many VG_(atfork) handlers requested: "
+ "raise VG_MAX_ATFORK");
+
+ atforks[n_atfork].pre = pre;
+ atforks[n_atfork].parent = parent;
+ atforks[n_atfork].child = child;
+
+ n_atfork++;
+}
+
+void VG_(do_atfork_pre)(ThreadId tid)
+{
+ Int i;
+
+ for(i = 0; i < n_atfork; i++)
+ if (atforks[i].pre != NULL)
+ (*atforks[i].pre)(tid);
+}
+
+void VG_(do_atfork_parent)(ThreadId tid)
+{
+ Int i;
+
+ for(i = 0; i < n_atfork; i++)
+ if (atforks[i].parent != NULL)
+ (*atforks[i].parent)(tid);
+}
+
+void VG_(do_atfork_child)(ThreadId tid)
+{
+ Int i;
+
+ for(i = 0; i < n_atfork; i++)
+ if (atforks[i].child != NULL)
+ (*atforks[i].child)(tid);
+}
+
+
/*--------------------------------------------------------------------*/
/*--- end ---*/
/*--------------------------------------------------------------------*/
diff --git a/include/basic_types.h b/include/basic_types.h
index 10c0f3599..6e02b3d03 100644
--- a/include/basic_types.h
+++ b/include/basic_types.h
@@ -71,6 +71,17 @@ typedef
UInt
ThreadId;
+/* An abstraction of syscall return values.
+ When .isError == False, val holds the return value.
+ When .isError == True, val holds the error code.
+*/
+typedef
+ struct {
+ UWord val;
+ Bool isError;
+ }
+ SysRes;
+
/* ---------------------------------------------------------------------
Where to send bug reports to.
------------------------------------------------------------------ */
diff --git a/include/pub_tool_tooliface.h b/include/pub_tool_tooliface.h
index 2c4590626..5514080b0 100644
--- a/include/pub_tool_tooliface.h
+++ b/include/pub_tool_tooliface.h
@@ -235,7 +235,7 @@ extern void VG_(needs_client_requests) (
// corresponding post_ function had better free() it!
extern void VG_(needs_syscall_wrapper) (
void (* pre_syscall)(ThreadId tid, UInt syscallno),
- void (*post_syscall)(ThreadId tid, UInt syscallno, Int res)
+ void (*post_syscall)(ThreadId tid, UInt syscallno, SysRes res)
);
/* Are tool-state sanity checks performed? */