From: Tom Hughes Date: Tue, 21 Mar 2006 10:58:35 +0000 (+0000) Subject: Add wrappers for a load of new 2.6.16 system calls. Fixes bug #123248. X-Git-Tag: svn/VALGRIND_3_2_0~174 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4eb782b5539f26688e91560038a641b2d2cd6622;p=thirdparty%2Fvalgrind.git 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 --- diff --git a/coregrind/m_syswrap/priv_syswrap-linux.h b/coregrind/m_syswrap/priv_syswrap-linux.h index addb5bc797..0837c1a533 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_prctl); 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_timer_delete); 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 4e6bd6ea26..de441878d4 100644 --- a/coregrind/m_syswrap/syswrap-amd64-linux.c +++ b/coregrind/m_syswrap/syswrap-amd64-linux.c @@ -1271,6 +1271,26 @@ const SyscallTableEntry ML_(syscall_table)[] = { 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 1338e3ff6e..0c272da617 100644 --- a/coregrind/m_syswrap/syswrap-generic.c +++ b/coregrind/m_syswrap/syswrap-generic.c @@ -2237,7 +2237,7 @@ POST(sys_pread64) 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_brk) 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_chown) 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_kill) 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 @@ POST(sys_newlstat) 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 @@ POST(sys_creat) } } -// XXX: x86-specific, due to pollfd struct PRE(sys_poll) { /* struct pollfd { @@ -4880,16 +4879,16 @@ PRE(sys_poll) *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 @@ POST(sys_poll) 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 @@ PRE(sys_readlink) 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 @@ POST(sys_readv) 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_rename) 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 @@ PRE(sys_select) 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 @@ POST(sys_newstat) 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 @@ POST(sys_statfs) 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 @@ POST(sys_statfs64) 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_writev) 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_utimes) 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 3ceebf25d3..bc9864823a 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 @@ POST(sys_futex) } } +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 @@ ML_(linux_POST_sys_msgctl) ( ThreadId tid, } } +/* --------------------------------------------------------------------- + *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//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//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 4861a7c685..949f082773 100644 --- a/coregrind/m_syswrap/syswrap-x86-linux.c +++ b/coregrind/m_syswrap/syswrap-x86-linux.c @@ -758,6 +758,7 @@ static void setup_child ( /*OUT*/ ThreadArchState *child, 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 @@ POST(sys_lstat64) 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(sys_stat64) 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 @@ const SyscallTableEntry ML_(syscall_table)[] = { 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) =