]> granicus.if.org Git - strace/blobdiff - syscall.c
ioctl: print unrecognized ioctl codes in _IOC(dir,type,nr,size) format
[strace] / syscall.c
index f8165510206d6e0a775246af4a9c4c82040fc6d7..a50910ffa072917e4b15cfcd0fae5dd84181586c 100644 (file)
--- a/syscall.c
+++ b/syscall.c
@@ -37,7 +37,9 @@
 
 #ifdef HAVE_SYS_REG_H
 # include <sys/reg.h>
-#elif defined(HAVE_LINUX_PTRACE_H)
+#endif
+
+#ifdef HAVE_LINUX_PTRACE_H
 # undef PTRACE_SYSCALL
 # ifdef HAVE_STRUCT_IA64_FPREG
 #  define ia64_fpreg XXX_ia64_fpreg
@@ -323,7 +325,7 @@ set_personality(int personality)
 }
 
 static void
-update_personality(struct tcb *tcp, int personality)
+update_personality(struct tcb *tcp, unsigned int personality)
 {
        if (personality == current_personality)
                return;
@@ -370,7 +372,7 @@ update_personality(struct tcb *tcp, int personality)
 static int qual_syscall(), qual_signal(), qual_desc();
 
 static const struct qual_options {
-       int bitflag;
+       unsigned int bitflag;
        const char *option_name;
        int (*qualify)(const char *, int, int);
        const char *argument_name;
@@ -396,7 +398,7 @@ static const struct qual_options {
 };
 
 static void
-reallocate_qual(int n)
+reallocate_qual(const unsigned int n)
 {
        unsigned p;
        qualbits_t *qp;
@@ -410,9 +412,9 @@ reallocate_qual(int n)
 }
 
 static void
-qualify_one(int n, int bitflag, int not, int pers)
+qualify_one(const unsigned int n, unsigned int bitflag, const int not, const int pers)
 {
-       unsigned p;
+       int p;
 
        if (num_quals <= n)
                reallocate_qual(n + 1);
@@ -428,10 +430,10 @@ qualify_one(int n, int bitflag, int not, int pers)
 }
 
 static int
-qual_syscall(const char *s, int bitflag, int not)
+qual_syscall(const char *s, const unsigned int bitflag, const int not)
 {
-       unsigned p;
-       unsigned i;
+       int p;
+       unsigned int i;
        int rc = -1;
 
        if (*s >= '0' && *s <= '9') {
@@ -457,9 +459,9 @@ qual_syscall(const char *s, int bitflag, int not)
 }
 
 static int
-qual_signal(const char *s, int bitflag, int not)
+qual_signal(const char *s, const unsigned int bitflag, const int not)
 {
-       int i;
+       unsigned int i;
 
        if (*s >= '0' && *s <= '9') {
                int signo = string_to_uint(s);
@@ -480,7 +482,7 @@ qual_signal(const char *s, int bitflag, int not)
 }
 
 static int
-qual_desc(const char *s, int bitflag, int not)
+qual_desc(const char *s, const unsigned int bitflag, const int not)
 {
        if (*s >= '0' && *s <= '9') {
                int desc = string_to_uint(s);
@@ -516,20 +518,20 @@ void
 qualify(const char *s)
 {
        const struct qual_options *opt;
-       int not;
        char *copy;
        const char *p;
-       int i, n;
+       int not;
+       unsigned int i;
 
        if (num_quals == 0)
                reallocate_qual(MIN_QUALS);
 
        opt = &qual_options[0];
        for (i = 0; (p = qual_options[i].option_name); i++) {
-               n = strlen(p);
-               if (strncmp(s, p, n) == 0 && s[n] == '=') {
+               unsigned int len = strlen(p);
+               if (strncmp(s, p, len) == 0 && s[len] == '=') {
                        opt = &qual_options[i];
-                       s += n + 1;
+                       s += len + 1;
                        break;
                }
        }
@@ -555,6 +557,7 @@ qualify(const char *s)
        if (!copy)
                die_out_of_memory();
        for (p = strtok(copy, ","); p; p = strtok(NULL, ",")) {
+               int n;
                if (opt->bitflag == QUAL_TRACE && (n = lookup_class(p)) > 0) {
                        unsigned pers;
                        for (pers = 0; pers < SUPPORTED_PERSONALITIES; pers++) {
@@ -927,34 +930,35 @@ print_pc(struct tcb *tcp)
 #endif /* architecture */
 }
 
-/* Shuffle syscall numbers so that we don't have huge gaps in syscall table.
- * The shuffling should be reversible: shuffle_scno(shuffle_scno(n)) == n.
+/*
+ * Shuffle syscall numbers so that we don't have huge gaps in syscall table.
+ * The shuffling should be an involution: shuffle_scno(shuffle_scno(n)) == n.
  */
 #if defined(ARM) || defined(AARCH64) /* So far only 32-bit ARM needs this */
 static long
 shuffle_scno(unsigned long scno)
 {
-       if (scno <= ARM_LAST_ORDINARY_SYSCALL)
+       if (scno < ARM_FIRST_SHUFFLED_SYSCALL)
                return scno;
 
        /* __ARM_NR_cmpxchg? Swap with LAST_ORDINARY+1 */
-       if (scno == 0x000ffff0)
-               return ARM_LAST_ORDINARY_SYSCALL+1;
-       if (scno == ARM_LAST_ORDINARY_SYSCALL+1)
+       if (scno == ARM_FIRST_SHUFFLED_SYSCALL)
                return 0x000ffff0;
+       if (scno == 0x000ffff0)
+               return ARM_FIRST_SHUFFLED_SYSCALL;
 
-       /* Is it ARM specific syscall?
-        * Swap with [LAST_ORDINARY+2, LAST_ORDINARY+2 + LAST_SPECIAL] range.
+#define ARM_SECOND_SHUFFLED_SYSCALL (ARM_FIRST_SHUFFLED_SYSCALL + 1)
+       /*
+        * Is it ARM specific syscall?
+        * Swap [0x000f0000, 0x000f0000 + LAST_SPECIAL] range
+        * with [SECOND_SHUFFLED, SECOND_SHUFFLED + LAST_SPECIAL] range.
         */
-       if (scno >= 0x000f0000
-        && scno <= 0x000f0000 + ARM_LAST_SPECIAL_SYSCALL
-       ) {
-               return scno - 0x000f0000 + (ARM_LAST_ORDINARY_SYSCALL+2);
+       if (scno >= 0x000f0000 &&
+           scno <= 0x000f0000 + ARM_LAST_SPECIAL_SYSCALL) {
+               return scno - 0x000f0000 + ARM_SECOND_SHUFFLED_SYSCALL;
        }
-       if (/* scno >= ARM_LAST_ORDINARY_SYSCALL+2 - always true */ 1
-        && scno <= (ARM_LAST_ORDINARY_SYSCALL+2) + ARM_LAST_SPECIAL_SYSCALL
-       ) {
-               return scno + 0x000f0000 - (ARM_LAST_ORDINARY_SYSCALL+2);
+       if (scno <= ARM_SECOND_SHUFFLED_SYSCALL + ARM_LAST_SPECIAL_SYSCALL) {
+               return scno + 0x000f0000 - ARM_SECOND_SHUFFLED_SYSCALL;
        }
 
        return scno;
@@ -1220,7 +1224,7 @@ get_scno(struct tcb *tcp)
 #elif defined(POWERPC)
        scno = ppc_regs.gpr[0];
 # ifdef POWERPC64
-       int currpers;
+       unsigned int currpers;
 
        /*
         * Check for 64/32 bit mode.
@@ -1242,7 +1246,7 @@ get_scno(struct tcb *tcp)
 # ifndef __X32_SYSCALL_BIT
 #  define __X32_SYSCALL_BIT    0x40000000
 # endif
-       int currpers;
+       unsigned int currpers;
 # if 1
        /* GETREGSET of NT_PRSTATUS tells us regset size,
         * which unambiguously detects i386.
@@ -1375,7 +1379,7 @@ get_scno(struct tcb *tcp)
        if (errno)
                return -1;
        /* EABI syscall convention? */
-       if (scno != 0xef000000) {
+       if ((unsigned long) scno != 0xef000000) {
                /* No, it's OABI */
                if ((scno & 0x0ff00000) != 0x0f900000) {
                        fprintf(stderr, "pid %d unknown syscall trap 0x%08lx\n",
@@ -1530,7 +1534,7 @@ get_scno(struct tcb *tcp)
        if (upeek(tcp->pid, 4*PT_R9, &scno) < 0)
                return -1;
 #elif defined(TILE)
-       int currpers;
+       unsigned int currpers;
        scno = tile_regs.regs[10];
 # ifdef __tilepro__
        currpers = 1;
@@ -2040,6 +2044,13 @@ trace_syscall_entering(struct tcb *tcp)
                goto ret;
        }
 
+#ifdef USE_LIBUNWIND
+       if (stack_trace_enabled) {
+               if (tcp->s_ent->sys_flags & STACKTRACE_CAPTURE_ON_ENTER)
+                       unwind_capture_stacktrace(tcp);
+       }
+#endif
+
        printleader(tcp);
        if (tcp->qual_flg & UNDEFINED_SCNO)
                tprintf("%s(", undefined_scno_name(tcp));
@@ -2487,6 +2498,12 @@ dumpio(struct tcb *tcp)
                        dumpstr(tcp, tcp->u_arg[1], tcp->u_rval);
                else if (func == sys_readv)
                        dumpiov(tcp, tcp->u_arg[2], tcp->u_arg[1]);
+#if HAVE_SENDMSG
+               else if (func == sys_recvmsg)
+                       dumpiov_in_msghdr(tcp, tcp->u_arg[1]);
+               else if (func == sys_recvmmsg)
+                       dumpiov_in_mmsghdr(tcp, tcp->u_arg[1]);
+#endif
                return;
        }
        if (qual_flags[tcp->u_arg[0]] & QUAL_WRITE) {
@@ -2497,6 +2514,12 @@ dumpio(struct tcb *tcp)
                        dumpstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
                else if (func == sys_writev)
                        dumpiov(tcp, tcp->u_arg[2], tcp->u_arg[1]);
+#if HAVE_SENDMSG
+               else if (func == sys_sendmsg)
+                       dumpiov_in_msghdr(tcp, tcp->u_arg[1]);
+               else if (func == sys_sendmmsg)
+                       dumpiov_in_mmsghdr(tcp, tcp->u_arg[1]);
+#endif
                return;
        }
 }
@@ -2513,6 +2536,13 @@ trace_syscall_exiting(struct tcb *tcp)
        if (Tflag || cflag)
                gettimeofday(&tv, NULL);
 
+#ifdef USE_LIBUNWIND
+       if (stack_trace_enabled) {
+               if (tcp->s_ent->sys_flags & STACKTRACE_INVALIDATE_CACHE)
+                       unwind_cache_invalidate(tcp);
+       }
+#endif
+
 #if SUPPORTED_PERSONALITIES > 1
        update_personality(tcp, tcp->currpers);
 #endif
@@ -2646,7 +2676,7 @@ trace_syscall_exiting(struct tcb *tcp)
                default:
                        if (u_error < 0)
                                tprintf("= -1 E??? (errno %ld)", u_error);
-                       else if (u_error < nerrnos)
+                       else if ((unsigned long) u_error < nerrnos)
                                tprintf("= -1 %s (%s)", errnoent[u_error],
                                        strerror(u_error));
                        else
@@ -2674,6 +2704,14 @@ trace_syscall_exiting(struct tcb *tcp)
                        case RVAL_DECIMAL:
                                tprintf("= %ld", tcp->u_rval);
                                break;
+                       case RVAL_FD:
+                               if (show_fd_path) {
+                                       tprints("= ");
+                                       printfd(tcp, tcp->u_rval);
+                               }
+                               else
+                                       tprintf("= %ld", tcp->u_rval);
+                               break;
 #if defined(LINUX_MIPSN32) || defined(X32)
                        /*
                        case RVAL_LHEX: