Add wrappers for a load of new 2.6.16 system calls. Fixes bug #123248.
Also expands pathname arguments as strings in a lot more system call
trace messages and fixed the poll wrapper to not be x86 specific.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@5785 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/m_syswrap/priv_syswrap-linux.h b/coregrind/m_syswrap/priv_syswrap-linux.h
index addb5bc..0837c1a 100644
--- a/coregrind/m_syswrap/priv_syswrap-linux.h
+++ b/coregrind/m_syswrap/priv_syswrap-linux.h
@@ -74,6 +74,8 @@
DECL_TEMPLATE(linux, sys_sendfile);
DECL_TEMPLATE(linux, sys_sendfile64);
DECL_TEMPLATE(linux, sys_futex);
+DECL_TEMPLATE(linux, sys_pselect6);
+DECL_TEMPLATE(linux, sys_ppoll);
DECL_TEMPLATE(linux, sys_epoll_create);
DECL_TEMPLATE(linux, sys_epoll_ctl);
@@ -122,6 +124,20 @@
DECL_TEMPLATE(linux, sys_capget);
DECL_TEMPLATE(linux, sys_capset);
+DECL_TEMPLATE(linux, sys_openat);
+DECL_TEMPLATE(linux, sys_mkdirat);
+DECL_TEMPLATE(linux, sys_mknodat);
+DECL_TEMPLATE(linux, sys_fchownat);
+DECL_TEMPLATE(linux, sys_futimesat);
+DECL_TEMPLATE(linux, sys_newfstatat);
+DECL_TEMPLATE(linux, sys_unlinkat);
+DECL_TEMPLATE(linux, sys_renameat);
+DECL_TEMPLATE(linux, sys_linkat);
+DECL_TEMPLATE(linux, sys_symlinkat);
+DECL_TEMPLATE(linux, sys_readlinkat);
+DECL_TEMPLATE(linux, sys_fchmodat);
+DECL_TEMPLATE(linux, sys_faccessat);
+
// These ones have 32-bit generic equivalents, but the 16-bit versions (they
// use 16-bit gid_t and uid_t types) seem to be Linux-specific.
DECL_TEMPLATE(linux, sys_getuid16);
diff --git a/coregrind/m_syswrap/syswrap-amd64-linux.c b/coregrind/m_syswrap/syswrap-amd64-linux.c
index 4e6bd6e..de44187 100644
--- a/coregrind/m_syswrap/syswrap-amd64-linux.c
+++ b/coregrind/m_syswrap/syswrap-amd64-linux.c
@@ -1271,6 +1271,26 @@
LINX_(__NR_inotify_add_watch, sys_inotify_add_watch), // 254
LINX_(__NR_inotify_rm_watch, sys_inotify_rm_watch), // 255
+// LINX_(__NR_migrate_pages, sys_migrate_pages), // 256
+ LINXY(__NR_openat, sys_openat), // 257
+ LINX_(__NR_mkdirat, sys_mkdirat), // 258
+ LINX_(__NR_mknodat, sys_mknodat), // 259
+
+ LINX_(__NR_fchownat, sys_fchownat), // 260
+ LINX_(__NR_futimesat, sys_futimesat), // 261
+ LINXY(__NR_newfstatat, sys_newfstatat), // 262
+ LINX_(__NR_unlinkat, sys_unlinkat), // 263
+ LINX_(__NR_renameat, sys_renameat), // 264
+
+ LINX_(__NR_linkat, sys_linkat), // 265
+ LINX_(__NR_symlinkat, sys_symlinkat), // 266
+ LINX_(__NR_readlinkat, sys_readlinkat), // 267
+ LINX_(__NR_fchmodat, sys_fchmodat), // 268
+ LINX_(__NR_faccessat, sys_faccessat), // 269
+
+// LINX_(__NR_pselect6, sys_ni_syscall), // 270
+// LINXY(__NR_ppoll, sys_ni_syscall), // 271
+// LINX_(__NR_unshare, sys_unshare), // 272
};
const UInt ML_(syscall_table_size) =
diff --git a/coregrind/m_syswrap/syswrap-generic.c b/coregrind/m_syswrap/syswrap-generic.c
index 1338e3f..0c272da 100644
--- a/coregrind/m_syswrap/syswrap-generic.c
+++ b/coregrind/m_syswrap/syswrap-generic.c
@@ -2237,7 +2237,7 @@
PRE(sys_mknod)
{
- PRINT("sys_mknod ( %p, 0x%x, 0x%x )", ARG1, ARG2, ARG3 );
+ PRINT("sys_mknod ( %p(%s), 0x%x, 0x%x )", ARG1, ARG1, ARG2, ARG3 );
PRE_REG_READ3(long, "mknod",
const char *, pathname, int, mode, unsigned, dev);
PRE_MEM_RASCIIZ( "mknod(pathname)", ARG1 );
@@ -2581,21 +2581,21 @@
PRE(sys_chdir)
{
- PRINT("sys_chdir ( %p )", ARG1);
+ PRINT("sys_chdir ( %p(%s) )", ARG1,ARG1);
PRE_REG_READ1(long, "chdir", const char *, path);
PRE_MEM_RASCIIZ( "chdir(path)", ARG1 );
}
PRE(sys_chmod)
{
- PRINT("sys_chmod ( %p, %d )", ARG1,ARG2);
+ PRINT("sys_chmod ( %p(%s), %d )", ARG1,ARG1,ARG2);
PRE_REG_READ2(long, "chmod", const char *, path, vki_mode_t, mode);
PRE_MEM_RASCIIZ( "chmod(path)", ARG1 );
}
PRE(sys_chown)
{
- PRINT("sys_chown ( %p, 0x%x, 0x%x )", ARG1,ARG2,ARG3);
+ PRINT("sys_chown ( %p(%s), 0x%x, 0x%x )", ARG1,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 );
@@ -2603,7 +2603,7 @@
PRE(sys_lchown)
{
- PRINT("sys_lchown ( %p, 0x%x, 0x%x )", ARG1,ARG2,ARG3);
+ PRINT("sys_lchown ( %p(%s), 0x%x, 0x%x )", ARG1,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 );
@@ -4587,7 +4587,7 @@
PRE(sys_link)
{
*flags |= SfMayBlock;
- PRINT("sys_link ( %p, %p)", ARG1, ARG2);
+ PRINT("sys_link ( %p(%s), %p(%s) )", ARG1,ARG1,ARG2,ARG2);
PRE_REG_READ2(long, "link", const char *, oldpath, const char *, newpath);
PRE_MEM_RASCIIZ( "link(oldpath)", ARG1);
PRE_MEM_RASCIIZ( "link(newpath)", ARG2);
@@ -4612,7 +4612,7 @@
PRE(sys_mkdir)
{
*flags |= SfMayBlock;
- PRINT("sys_mkdir ( %p, %d )", ARG1,ARG2);
+ PRINT("sys_mkdir ( %p(%s), %d )", ARG1,ARG1,ARG2);
PRE_REG_READ2(long, "mkdir", const char *, pathname, int, mode);
PRE_MEM_RASCIIZ( "mkdir(pathname)", ARG1 );
}
@@ -4865,7 +4865,6 @@
}
}
-// XXX: x86-specific, due to pollfd struct
PRE(sys_poll)
{
/* struct pollfd {
@@ -4880,16 +4879,16 @@
*flags |= SfMayBlock;
PRINT("sys_poll ( %p, %d, %d )\n", ARG1,ARG2,ARG3);
PRE_REG_READ3(long, "poll",
- struct pollfd *, ufds, unsigned int, nfds, long, timeout);
-
+ struct vki_pollfd *, ufds, unsigned int, nfds, long, timeout);
+
for (i = 0; i < ARG2; i++) {
- // 'fd' and 'events' field are inputs; 'revents' is output.
- // XXX: this is x86 specific -- the pollfd struct varies across
- // different architectures.
- PRE_MEM_READ( "poll(ufds)",
- (Addr)(&ufds[i]), sizeof(int) + sizeof(short) );
- PRE_MEM_WRITE( "poll(ufds)", (Addr)(&ufds[i].revents), sizeof(short) );
- }
+ PRE_MEM_READ( "poll(ufds.fd)",
+ (Addr)(&ufds[i].fd), sizeof(ufds[i].fd) );
+ PRE_MEM_READ( "poll(ufds.events)",
+ (Addr)(&ufds[i].events), sizeof(ufds[i].events) );
+ PRE_MEM_WRITE( "poll(ufd.reventss)",
+ (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
+ }
}
POST(sys_poll)
@@ -4897,9 +4896,8 @@
if (RES > 0) {
UInt i;
struct vki_pollfd* ufds = (struct vki_pollfd *)ARG1;
- // XXX: again, this is x86-specific
for (i = 0; i < ARG2; i++)
- POST_MEM_WRITE( (Addr)(&ufds[i].revents), sizeof(Short) );
+ POST_MEM_WRITE( (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
}
}
@@ -4908,7 +4906,7 @@
HChar name[25];
Word saved = SYSNO;
- PRINT("sys_readlink ( %p, %p, %llu )", ARG1,ARG2,(ULong)ARG3);
+ PRINT("sys_readlink ( %p(%s), %p, %llu )", ARG1,ARG1,ARG2,(ULong)ARG3);
PRE_REG_READ3(long, "readlink",
const char *, path, char *, buf, int, bufsiz);
PRE_MEM_RASCIIZ( "readlink(path)", ARG1 );
@@ -4979,7 +4977,7 @@
PRE(sys_rename)
{
- PRINT("sys_rename ( %p, %p )", ARG1, ARG2 );
+ PRINT("sys_rename ( %p(%s), %p(%s) )", ARG1,ARG1,ARG2,ARG2);
PRE_REG_READ2(long, "rename", const char *, oldpath, const char *, newpath);
PRE_MEM_RASCIIZ( "rename(oldpath)", ARG1 );
PRE_MEM_RASCIIZ( "rename(newpath)", ARG2 );
@@ -4988,7 +4986,7 @@
PRE(sys_rmdir)
{
*flags |= SfMayBlock;
- PRINT("sys_rmdir ( %p )", ARG1);
+ PRINT("sys_rmdir ( %p(%s) )", ARG1,ARG1);
PRE_REG_READ1(long, "rmdir", const char *, pathname);
PRE_MEM_RASCIIZ( "rmdir(pathname)", ARG1 );
}
@@ -4999,7 +4997,7 @@
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,
- vki_fd_set *, exceptfds, struct timeval *, timeout);
+ vki_fd_set *, exceptfds, struct vki_timeval *, timeout);
// XXX: this possibly understates how much memory is read.
if (ARG2 != 0)
PRE_MEM_READ( "select(readfds)",
@@ -5113,7 +5111,7 @@
PRE(sys_statfs)
{
- PRINT("sys_statfs ( %p, %p )",ARG1,ARG2);
+ PRINT("sys_statfs ( %p(%s), %p )",ARG1,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) );
@@ -5125,7 +5123,7 @@
PRE(sys_statfs64)
{
- PRINT("sys_statfs64 ( %p, %llu, %p )",ARG1,(ULong)ARG2,ARG3);
+ PRINT("sys_statfs64 ( %p(%s), %llu, %p )",ARG1,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 );
@@ -5139,7 +5137,7 @@
PRE(sys_symlink)
{
*flags |= SfMayBlock;
- PRINT("sys_symlink ( %p, %p )",ARG1,ARG2);
+ PRINT("sys_symlink ( %p(%s), %p(%s) )",ARG1,ARG1,ARG2,ARG2);
PRE_REG_READ2(long, "symlink", const char *, oldpath, const char *, newpath);
PRE_MEM_RASCIIZ( "symlink(oldpath)", ARG1 );
PRE_MEM_RASCIIZ( "symlink(newpath)", ARG2 );
@@ -5271,7 +5269,7 @@
PRE(sys_utimes)
{
- PRINT("sys_utimes ( %p, %p )", ARG1,ARG2);
+ PRINT("sys_utimes ( %p(%s), %p )", ARG1,ARG1,ARG2);
PRE_REG_READ2(long, "utimes", char *, filename, struct timeval *, tvp);
PRE_MEM_RASCIIZ( "utimes(filename)", ARG1 );
if (ARG2 != 0)
@@ -5280,7 +5278,7 @@
PRE(sys_acct)
{
- PRINT("sys_acct ( %p )", ARG1);
+ PRINT("sys_acct ( %p(%s) )", ARG1,ARG1);
PRE_REG_READ1(long, "acct", const char *, filename);
PRE_MEM_RASCIIZ( "acct(filename)", ARG1 );
}
diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c
index 3ceebf2..bc98648 100644
--- a/coregrind/m_syswrap/syswrap-linux.c
+++ b/coregrind/m_syswrap/syswrap-linux.c
@@ -33,6 +33,7 @@
#include "pub_core_aspacemgr.h"
#include "pub_core_debuginfo.h" // VG_(di_notify_*)
#include "pub_core_transtab.h" // VG_(discard_translations)
+#include "pub_core_clientstate.h"
#include "pub_core_debuglog.h"
#include "pub_core_libcbase.h"
#include "pub_core_libcassert.h"
@@ -798,6 +799,66 @@
}
}
+PRE(sys_pselect6)
+{
+ *flags |= SfMayBlock;
+ PRINT("sys_pselect6 ( %d, %p, %p, %p, %p, %p )", ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
+ PRE_REG_READ6(long, "pselect6",
+ int, n, vki_fd_set *, readfds, vki_fd_set *, writefds,
+ vki_fd_set *, exceptfds, struct vki_timeval *, timeout,
+ void *, sig);
+ // XXX: this possibly understates how much memory is read.
+ if (ARG2 != 0)
+ PRE_MEM_READ( "pselect6(readfds)",
+ ARG2, ARG1/8 /* __FD_SETSIZE/8 */ );
+ if (ARG3 != 0)
+ PRE_MEM_READ( "pselect6(writefds)",
+ ARG3, ARG1/8 /* __FD_SETSIZE/8 */ );
+ if (ARG4 != 0)
+ PRE_MEM_READ( "pselect6(exceptfds)",
+ ARG4, ARG1/8 /* __FD_SETSIZE/8 */ );
+ if (ARG5 != 0)
+ PRE_MEM_READ( "pselect6(timeout)", ARG5, sizeof(struct vki_timeval) );
+ if (ARG6 != 0)
+ PRE_MEM_READ( "pselect6(sig)", ARG6, sizeof(void *)+sizeof(vki_size_t) );
+}
+
+PRE(sys_ppoll)
+{
+ UInt i;
+ struct vki_pollfd* ufds = (struct vki_pollfd *)ARG1;
+ *flags |= SfMayBlock;
+ PRINT("sys_ppoll ( %p, %d, %p, %p, %llu )\n", ARG1,ARG2,ARG3,ARG4,ARG5);
+ PRE_REG_READ5(long, "ppoll",
+ struct vki_pollfd *, ufds, unsigned int, nfds,
+ struct vki_timespec *, tsp, vki_sigset_t *, sigmask,
+ vki_size_t, sigsetsize);
+
+ for (i = 0; i < ARG2; i++) {
+ PRE_MEM_READ( "ppoll(ufds.fd)",
+ (Addr)(&ufds[i].fd), sizeof(ufds[i].fd) );
+ PRE_MEM_READ( "ppoll(ufds.events)",
+ (Addr)(&ufds[i].events), sizeof(ufds[i].events) );
+ PRE_MEM_WRITE( "ppoll(ufd.reventss)",
+ (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
+ }
+
+ if (ARG3)
+ PRE_MEM_READ( "ppoll(tsp)", ARG3, sizeof(struct vki_timespec) );
+ if (ARG4)
+ PRE_MEM_READ( "ppoll(sigmask)", ARG4, sizeof(vki_sigset_t) );
+}
+
+POST(sys_ppoll)
+{
+ if (RES > 0) {
+ UInt i;
+ struct vki_pollfd* ufds = (struct vki_pollfd *)ARG1;
+ for (i = 0; i < ARG2; i++)
+ POST_MEM_WRITE( (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
+ }
+}
+
/* ---------------------------------------------------------------------
epoll_* wrappers
@@ -2215,6 +2276,201 @@
}
}
+/* ---------------------------------------------------------------------
+ *at wrappers
+ ------------------------------------------------------------------ */
+
+PRE(sys_openat)
+{
+ HChar name[30];
+ SysRes sres;
+
+ if (ARG3 & VKI_O_CREAT) {
+ // 4-arg version
+ PRINT("sys_openat ( %d, %p(%s), %d, %d )",ARG1,ARG2,ARG2,ARG3,ARG4);
+ PRE_REG_READ4(long, "openat",
+ int, dfd, const char *, filename, int, flags, int, mode);
+ } else {
+ // 3-arg version
+ PRINT("sys_openat ( %d, %p(%s), %d )",ARG1,ARG2,ARG2,ARG3);
+ PRE_REG_READ3(long, "openat",
+ int, dfd, const char *, filename, int, flags);
+ }
+
+ if (!ML_(fd_allowed)(ARG1, "openat", tid, False))
+ SET_STATUS_Failure( VKI_EBADF );
+ else
+ PRE_MEM_RASCIIZ( "openat(filename)", ARG2 );
+
+ /* Handle the case where the open is of /proc/self/cmdline or
+ /proc/<pid>/cmdline, and just give it a copy of the fd for the
+ fake file we cooked up at startup (in m_main). Also, seek the
+ cloned fd back to the start. */
+
+ VG_(sprintf)(name, "/proc/%d/cmdline", VG_(getpid)());
+ if (ML_(safe_to_deref)( (void*)ARG2, 1 )
+ && (VG_(strcmp)((Char *)ARG2, name) == 0
+ || VG_(strcmp)((Char *)ARG2, "/proc/self/cmdline") == 0)) {
+ sres = VG_(dup)( VG_(cl_cmdline_fd) );
+ SET_STATUS_from_SysRes( sres );
+ if (!sres.isError) {
+ OffT off = VG_(lseek)( sres.val, 0, VKI_SEEK_SET );
+ if (off < 0)
+ SET_STATUS_Failure( VKI_EMFILE );
+ }
+ return;
+ }
+
+ /* Otherwise handle normally */
+ *flags |= SfMayBlock;
+}
+
+POST(sys_openat)
+{
+ vg_assert(SUCCESS);
+ if (!ML_(fd_allowed)(RES, "openat", tid, True)) {
+ VG_(close)(RES);
+ SET_STATUS_Failure( VKI_EMFILE );
+ } else {
+ if (VG_(clo_track_fds))
+ ML_(record_fd_open_with_given_name)(tid, RES, (Char*)ARG2);
+ }
+}
+
+PRE(sys_mkdirat)
+{
+ *flags |= SfMayBlock;
+ PRINT("sys_mkdirat ( %d, %p(%s), %d )", ARG1,ARG2,ARG2,ARG3);
+ PRE_REG_READ3(long, "mkdirat",
+ int, dfd, const char *, pathname, int, mode);
+ PRE_MEM_RASCIIZ( "mkdirat(pathname)", ARG2 );
+}
+
+PRE(sys_mknodat)
+{
+ PRINT("sys_mknodat ( %d, %p(%s), 0x%x, 0x%x )", ARG1,ARG2,ARG2,ARG3,ARG4 );
+ PRE_REG_READ4(long, "mknodat",
+ int, dfd, const char *, pathname, int, mode, unsigned, dev);
+ PRE_MEM_RASCIIZ( "mknodat(pathname)", ARG2 );
+}
+
+PRE(sys_fchownat)
+{
+ PRINT("sys_fchownat ( %d, %p(%s), 0x%x, 0x%x )", ARG1,ARG2,ARG2,ARG3,ARG4);
+ PRE_REG_READ4(long, "fchownat",
+ int, dfd, const char *, path,
+ vki_uid_t, owner, vki_gid_t, group);
+ PRE_MEM_RASCIIZ( "fchownat(path)", ARG2 );
+}
+
+PRE(sys_futimesat)
+{
+ PRINT("sys_futimesat ( %d, %p(%s), %p )", ARG1,ARG2,ARG2,ARG3);
+ PRE_REG_READ3(long, "futimesat",
+ int, dfd, char *, filename, struct timeval *, tvp);
+ PRE_MEM_RASCIIZ( "futimesat(filename)", ARG2 );
+ if (ARG3 != 0)
+ PRE_MEM_READ( "futimesat(tvp)", ARG3, sizeof(struct vki_timeval) );
+}
+
+PRE(sys_newfstatat)
+{
+ PRINT("sys_newfstatat ( %d, %p(%s), %p )", ARG1,ARG2,ARG2,ARG3);
+ PRE_REG_READ3(long, "fstatat",
+ int, dfd, char *, file_name, struct stat *, buf);
+ PRE_MEM_RASCIIZ( "fstatat(file_name)", ARG2 );
+ PRE_MEM_WRITE( "fstatat(buf)", ARG3, sizeof(struct vki_stat) );
+}
+
+POST(sys_newfstatat)
+{
+ POST_MEM_WRITE( ARG3, sizeof(struct vki_stat) );
+}
+
+PRE(sys_unlinkat)
+{
+ *flags |= SfMayBlock;
+ PRINT("sys_unlinkat ( %d, %p(%s) )", ARG1,ARG2,ARG2);
+ PRE_REG_READ2(long, "unlinkat", int, dfd, const char *, pathname);
+ PRE_MEM_RASCIIZ( "unlinkat(pathname)", ARG2 );
+}
+
+PRE(sys_renameat)
+{
+ PRINT("sys_renameat ( %d, %p(%s), %p(%s) )", ARG1,ARG2,ARG2,ARG3,ARG3);
+ PRE_REG_READ3(long, "renameat",
+ int, dfd, const char *, oldpath, const char *, newpath);
+ PRE_MEM_RASCIIZ( "renameat(oldpath)", ARG2 );
+ PRE_MEM_RASCIIZ( "renameat(newpath)", ARG3 );
+}
+
+PRE(sys_linkat)
+{
+ *flags |= SfMayBlock;
+ PRINT("sys_linkat ( %d, %p(%s), %p(%s) )", ARG1,ARG2,ARG2,ARG3,ARG3);
+ PRE_REG_READ3(long, "linkat",
+ int, dfd, const char *, oldpath, const char *, newpath);
+ PRE_MEM_RASCIIZ( "linkat(oldpath)", ARG2);
+ PRE_MEM_RASCIIZ( "linkat(newpath)", ARG3);
+}
+
+PRE(sys_symlinkat)
+{
+ *flags |= SfMayBlock;
+ PRINT("sys_symlinkat ( %d, %p(%s), %p(%s) )",ARG1,ARG2,ARG2,ARG3,ARG3);
+ PRE_REG_READ3(long, "symlinkat",
+ int, dfd, const char *, oldpath, const char *, newpath);
+ PRE_MEM_RASCIIZ( "symlinkat(oldpath)", ARG2 );
+ PRE_MEM_RASCIIZ( "symlinkat(newpath)", ARG3 );
+}
+
+PRE(sys_readlinkat)
+{
+ HChar name[25];
+ Word saved = SYSNO;
+
+ PRINT("sys_readlinkat ( %d, %p(%s), %p, %llu )", ARG1,ARG2,ARG2,ARG3,(ULong)ARG4);
+ PRE_REG_READ4(long, "readlinkat",
+ int, dfd, const char *, path, char *, buf, int, bufsiz);
+ PRE_MEM_RASCIIZ( "readlinkat(path)", ARG2 );
+ PRE_MEM_WRITE( "readlinkat(buf)", ARG3,ARG4 );
+
+ /*
+ * Handle the case where readlinkat is looking at /proc/self/exe or
+ * /proc/<pid>/exe.
+ */
+ VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
+ if (ML_(safe_to_deref)((void*)ARG2, 1)
+ && (VG_(strcmp)((Char *)ARG2, name) == 0
+ || VG_(strcmp)((Char *)ARG2, "/proc/self/exe") == 0)) {
+ VG_(sprintf)(name, "/proc/self/fd/%d", VG_(cl_exec_fd));
+ SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, (UWord)name,
+ ARG3, ARG4));
+ } else {
+ /* Normal case */
+ SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, ARG2, ARG3, ARG4));
+ }
+
+ if (SUCCESS && RES > 0)
+ POST_MEM_WRITE( ARG3, RES );
+}
+
+PRE(sys_fchmodat)
+{
+ PRINT("sys_fchmodat ( %d, %p(%s), %d )", ARG1,ARG2,ARG2,ARG3);
+ PRE_REG_READ3(long, "fchmodat",
+ int, dfd, const char *, path, vki_mode_t, mode);
+ PRE_MEM_RASCIIZ( "fchmodat(path)", ARG2 );
+}
+
+PRE(sys_faccessat)
+{
+ PRINT("sys_faccessat ( %d, %p(%s), %d )", ARG1,ARG2,ARG2,ARG3);
+ PRE_REG_READ3(long, "faccessat",
+ int, dfd, const char *, pathname, int, mode);
+ PRE_MEM_RASCIIZ( "faccessat(pathname)", ARG2 );
+}
+
#undef PRE
#undef POST
diff --git a/coregrind/m_syswrap/syswrap-x86-linux.c b/coregrind/m_syswrap/syswrap-x86-linux.c
index 4861a7c..949f082 100644
--- a/coregrind/m_syswrap/syswrap-x86-linux.c
+++ b/coregrind/m_syswrap/syswrap-x86-linux.c
@@ -758,6 +758,7 @@
magic. */
DECL_TEMPLATE(x86_linux, sys_socketcall);
DECL_TEMPLATE(x86_linux, sys_stat64);
+DECL_TEMPLATE(x86_linux, sys_fstatat64);
DECL_TEMPLATE(x86_linux, sys_fstat64);
DECL_TEMPLATE(x86_linux, sys_lstat64);
DECL_TEMPLATE(x86_linux, sys_clone);
@@ -1332,7 +1333,7 @@
PRE(sys_stat64)
{
- PRINT("sys_stat64 ( %p, %p )",ARG1,ARG2);
+ PRINT("sys_stat64 ( %p(%s), %p )",ARG1,ARG2,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) );
@@ -1343,6 +1344,20 @@
POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
}
+PRE(sys_fstatat64)
+{
+ PRINT("sys_fstatat64 ( %d, %p(%s), %p )",ARG1,ARG2,ARG2,ARG3);
+ PRE_REG_READ3(long, "fstatat64",
+ int, dfd, char *, file_name, struct stat64 *, buf);
+ PRE_MEM_RASCIIZ( "fstatat64(file_name)", ARG2 );
+ PRE_MEM_WRITE( "fstatat64(buf)", ARG3, sizeof(struct vki_stat64) );
+}
+
+POST(sys_fstatat64)
+{
+ POST_MEM_WRITE( ARG3, sizeof(struct vki_stat64) );
+}
+
PRE(sys_fstat64)
{
PRINT("sys_fstat64 ( %d, %p )",ARG1,ARG2);
@@ -2117,6 +2132,27 @@
LINX_(__NR_inotify_init, sys_inotify_init), // 291
LINX_(__NR_inotify_add_watch, sys_inotify_add_watch), // 292
LINX_(__NR_inotify_rm_watch, sys_inotify_rm_watch), // 293
+// LINX_(__NR_migrate_pages, sys_migrate_pages), // 294
+
+ LINXY(__NR_openat, sys_openat), // 295
+ LINX_(__NR_mkdirat, sys_mkdirat), // 296
+ LINX_(__NR_mknodat, sys_mknodat), // 297
+ LINX_(__NR_fchownat, sys_fchownat), // 298
+ LINX_(__NR_futimesat, sys_futimesat), // 299
+
+ PLAXY(__NR_fstatat64, sys_fstatat64), // 300
+ LINX_(__NR_unlinkat, sys_unlinkat), // 301
+ LINX_(__NR_renameat, sys_renameat), // 302
+ LINX_(__NR_linkat, sys_linkat), // 303
+ LINX_(__NR_symlinkat, sys_symlinkat), // 304
+
+ LINX_(__NR_readlinkat, sys_readlinkat), // 305
+ LINX_(__NR_fchmodat, sys_fchmodat), // 306
+ LINX_(__NR_faccessat, sys_faccessat), // 307
+ LINX_(__NR_pselect6, sys_pselect6), // 308
+ LINXY(__NR_ppoll, sys_ppoll), // 309
+
+// LINX_(__NR_unshare, sys_unshare), // 310
};
const UInt ML_(syscall_table_size) =