X-Git-Url: https://granicus.if.org/sourcecode?a=blobdiff_plain;f=desc.c;h=48824697fc090f48a4bab68177fa661c5440e86f;hb=3fb78d7305cd5b38bbed2d91b328c3181207b4e9;hp=0093538ee8aa85502dc120715a55ae62c9eca2a3;hpb=4cb5ccca247ca1560ce711e35c430805034e4c6b;p=strace diff --git a/desc.c b/desc.c index 0093538e..48824697 100644 --- a/desc.c +++ b/desc.c @@ -29,212 +29,6 @@ */ #include "defs.h" -#include -#include - -#include "xlat/fcntlcmds.h" -#include "xlat/fdflags.h" -#include "xlat/flockcmds.h" -#include "xlat/lockfcmds.h" -#include "xlat/notifyflags.h" - -/* - * Assume that F_SETLK64, F_SETLKW64, and F_GETLK64 are either defined - * or not defined altogether. - */ -#if defined(F_SETLK64) && F_SETLK64 + 0 != F_SETLK -# define USE_PRINTFLOCK64 1 -#else -# define USE_PRINTFLOCK64 0 -#endif - -#if USE_PRINTFLOCK64 - -# ifndef HAVE_STRUCT_FLOCK64 -struct flock64 { - short int l_type, l_whence; - int64_t l_start, l_len; - int l_pid; -}; -# endif - -static void -printflock64(struct tcb *tcp, long addr, int getlk) -{ - struct flock64 fl; - - if (umove_or_printaddr(tcp, addr, &fl)) - return; - tprints("{type="); - printxval(lockfcmds, fl.l_type, "F_???"); - tprints(", whence="); - printxval(whence_codes, fl.l_whence, "SEEK_???"); - tprintf(", start=%lld, len=%lld", (long long) fl.l_start, (long long) fl.l_len); - if (getlk) - tprintf(", pid=%lu}", (unsigned long) fl.l_pid); - else - tprints("}"); -} -#endif /* USE_PRINTFLOCK64 */ - -static void -printflock(struct tcb *tcp, long addr, int getlk) -{ - struct flock fl; - -#if SUPPORTED_PERSONALITIES > 1 - if ( -# if SIZEOF_OFF_T > SIZEOF_LONG - current_personality != DEFAULT_PERSONALITY && -# endif - current_wordsize != sizeof(fl.l_start)) { - if (current_wordsize == 4) { - /* 32-bit x86 app on x86_64 and similar cases */ - struct { - short int l_type; - short int l_whence; - int32_t l_start; /* off_t */ - int32_t l_len; /* off_t */ - int32_t l_pid; /* pid_t */ - } fl32; - if (umove_or_printaddr(tcp, addr, &fl32)) - return; - fl.l_type = fl32.l_type; - fl.l_whence = fl32.l_whence; - fl.l_start = fl32.l_start; - fl.l_len = fl32.l_len; - fl.l_pid = fl32.l_pid; - } else { - /* let people know we have a problem here */ - tprintf("", - current_wordsize); - return; - } - } else -#endif - if (umove_or_printaddr(tcp, addr, &fl)) - return; - tprints("{type="); - printxval(lockfcmds, fl.l_type, "F_???"); - tprints(", whence="); - printxval(whence_codes, fl.l_whence, "SEEK_???"); -#if SIZEOF_OFF_T > SIZEOF_LONG - tprintf(", start=%lld, len=%lld", fl.l_start, fl.l_len); -#else - tprintf(", start=%ld, len=%ld", fl.l_start, fl.l_len); -#endif - if (getlk) - tprintf(", pid=%lu}", (unsigned long) fl.l_pid); - else - tprints("}"); -} - -SYS_FUNC(fcntl) -{ - if (entering(tcp)) { - printfd(tcp, tcp->u_arg[0]); - tprints(", "); - printxval(fcntlcmds, tcp->u_arg[1], "F_???"); - switch (tcp->u_arg[1]) { - case F_SETFD: - tprints(", "); - printflags(fdflags, tcp->u_arg[2], "FD_???"); - break; - case F_SETOWN: case F_DUPFD: -#ifdef F_DUPFD_CLOEXEC - case F_DUPFD_CLOEXEC: -#endif - tprintf(", %ld", tcp->u_arg[2]); - break; - case F_SETFL: - tprints(", "); - tprint_open_modes(tcp->u_arg[2]); - break; - case F_SETLK: case F_SETLKW: - tprints(", "); - printflock(tcp, tcp->u_arg[2], 0); - break; -#if USE_PRINTFLOCK64 - case F_SETLK64: case F_SETLKW64: - tprints(", "); - printflock64(tcp, tcp->u_arg[2], 0); - break; -#endif /* USE_PRINTFLOCK64 */ -#ifdef F_NOTIFY - case F_NOTIFY: - tprints(", "); - printflags(notifyflags, tcp->u_arg[2], "DN_???"); - break; -#endif -#ifdef F_SETLEASE - case F_SETLEASE: - tprints(", "); - printxval(lockfcmds, tcp->u_arg[2], "F_???"); - break; -#endif - } - } else { - switch (tcp->u_arg[1]) { - case F_DUPFD: -#ifdef F_DUPFD_CLOEXEC - case F_DUPFD_CLOEXEC: -#endif - case F_SETFD: case F_SETFL: - case F_SETLK: case F_SETLKW: - case F_SETOWN: case F_GETOWN: -#ifdef F_NOTIFY - case F_NOTIFY: -#endif -#ifdef F_SETLEASE - case F_SETLEASE: -#endif - break; - case F_GETFD: - if (syserror(tcp) || tcp->u_rval == 0) - return 0; - tcp->auxstr = sprintflags("flags ", fdflags, tcp->u_rval); - return RVAL_HEX|RVAL_STR; - case F_GETFL: - if (syserror(tcp)) - return 0; - tcp->auxstr = sprint_open_modes(tcp->u_rval); - return RVAL_HEX|RVAL_STR; - case F_GETLK: - tprints(", "); - printflock(tcp, tcp->u_arg[2], 1); - break; -#if USE_PRINTFLOCK64 - case F_GETLK64: - tprints(", "); - printflock64(tcp, tcp->u_arg[2], 1); - break; -#endif -#ifdef F_GETLEASE - case F_GETLEASE: - if (syserror(tcp)) - return 0; - tcp->auxstr = xlookup(lockfcmds, tcp->u_rval); - return RVAL_HEX|RVAL_STR; -#endif - default: - tprintf(", %#lx", tcp->u_arg[2]); - break; - } - } - return 0; -} - -#ifdef LOCK_SH - -SYS_FUNC(flock) -{ - printfd(tcp, tcp->u_arg[0]); - tprints(", "); - printflags(flockcmds, tcp->u_arg[1], "LOCK_???"); - - return RVAL_DECODED; -} -#endif /* LOCK_SH */ SYS_FUNC(close) { @@ -274,25 +68,18 @@ SYS_FUNC(dup3) return do_dup2(tcp, 2); } -#if defined(ALPHA) -SYS_FUNC(getdtablesize) -{ - return 0; -} -#endif - static int -decode_select(struct tcb *tcp, long *args, - void (*print_tv_ts) (struct tcb *, const long), - const char * (*sprint_tv_ts) (struct tcb *, const long)) +decode_select(struct tcb *const tcp, const kernel_ulong_t *const args, + void (*const print_tv_ts) (struct tcb *, kernel_ulong_t), + const char * (*const sprint_tv_ts) (struct tcb *, kernel_ulong_t)) { int i, j; int nfds, fdsize; fd_set *fds = NULL; const char *sep; - long arg; + kernel_ulong_t addr; - /* Kernel truncates arg[0] to int, we do the same. */ + /* Kernel truncates args[0] to int, we do the same. */ nfds = (int) args[0]; /* Kernel rejects negative nfds, so we don't parse it either. */ @@ -315,13 +102,13 @@ decode_select(struct tcb *tcp, long *args, if (verbose(tcp) && fdsize > 0) fds = malloc(fdsize); for (i = 0; i < 3; i++) { - arg = args[i+1]; + addr = args[i+1]; tprints(", "); if (!fds) { - printaddr(arg); + printaddr(addr); continue; } - if (umoven_or_printaddr(tcp, arg, fdsize, fds)) + if (umoven_or_printaddr(tcp, addr, fdsize, fds)) continue; tprints("["); for (j = 0, sep = "";; j++) { @@ -359,8 +146,8 @@ decode_select(struct tcb *tcp, long *args, for (i = 0; i < 3 && ready_fds > 0; i++) { int first = 1; - arg = args[i+1]; - if (!arg || !fds || umoven(tcp, arg, fdsize, fds) < 0) + addr = args[i+1]; + if (!addr || !fds || umoven(tcp, addr, fdsize, fds) < 0) continue; for (j = 0;; j++) { j = next_set_bit(fds, j, nfds); @@ -405,26 +192,26 @@ decode_select(struct tcb *tcp, long *args, SYS_FUNC(oldselect) { - long long_args[5]; -#undef oldselect_args -#if SIZEOF_LONG == 4 -# define oldselect_args long_args -#else + kernel_ulong_t select_args[5]; unsigned int oldselect_args[5]; - unsigned int i; -#endif - if (umove(tcp, tcp->u_arg[0], &oldselect_args) < 0) { - printaddr(tcp->u_arg[0]); - return 0; - } -#ifndef oldselect_args - for (i = 0; i < 5; i++) { - long_args[i] = oldselect_args[i]; + if (sizeof(*select_args) == sizeof(*oldselect_args)) { + if (umove_or_printaddr(tcp, tcp->u_arg[0], &select_args)) { + return 0; + } + } else { + unsigned int i; + + if (umove_or_printaddr(tcp, tcp->u_arg[0], &oldselect_args)) { + return 0; + } + + for (i = 0; i < 5; ++i) { + select_args[i] = oldselect_args[i]; + } } -#endif - return decode_select(tcp, long_args, print_timeval, sprint_timeval); -#undef oldselect_args + + return decode_select(tcp, select_args, print_timeval, sprint_timeval); } #ifdef ALPHA @@ -439,20 +226,41 @@ SYS_FUNC(select) return decode_select(tcp, tcp->u_arg, print_timeval, sprint_timeval); } +static int +umove_kulong_array_or_printaddr(struct tcb *const tcp, const kernel_ulong_t addr, + kernel_ulong_t *const ptr, const size_t n) +{ +#ifndef current_klongsize + if (current_klongsize < sizeof(*ptr)) { + uint32_t ptr32[n]; + int r = umove_or_printaddr(tcp, addr, &ptr32); + if (!r) { + size_t i; + + for (i = 0; i < n; ++i) + ptr[i] = ptr32[i]; + } + return r; + } +#endif /* !current_klongsize */ + return umoven_or_printaddr(tcp, addr, n * sizeof(*ptr), ptr); +} + SYS_FUNC(pselect6) { int rc = decode_select(tcp, tcp->u_arg, print_timespec, sprint_timespec); if (entering(tcp)) { - unsigned long data[2]; + kernel_ulong_t data[2]; tprints(", "); - if (!umove_ulong_array_or_printaddr(tcp, tcp->u_arg[5], data, - ARRAY_SIZE(data))) { + if (!umove_kulong_array_or_printaddr(tcp, tcp->u_arg[5], + data, ARRAY_SIZE(data))) { tprints("{"); - /* NB: kernel requires data[1] == NSIG / 8 */ + /* NB: kernel requires data[1] == NSIG_BYTES */ print_sigset_addr_len(tcp, data[0], data[1]); - tprintf(", %lu}", data[1]); + tprintf(", %" PRI_klu "}", data[1]); } } + return rc; }