]> granicus.if.org Git - strace/blobdiff - system.c
Get rid of TCB_INUSE and TCB_STRACE_CHILD
[strace] / system.c
index 61a614a7fe4e70138548848d54bef97a6fe703b3..26d0d7fd2eb2d96f60f3840dbaabbcb2333bf90a 100644 (file)
--- a/system.c
+++ b/system.c
@@ -26,8 +26,6 @@
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *     $Id$
  */
 
 #include "defs.h"
@@ -58,6 +56,7 @@
 #define MS_KERNMOUNT   (1<<22)
 #define MS_I_VERSION   (1<<23)
 #define MS_STRICTATIME (1<<24)
+#define MS_NOSEC       (1<<28)
 #define MS_BORN                (1<<29)
 #define MS_ACTIVE      (1<<30)
 #define MS_NOUSER      (1<<31)
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
-
-#include <sys/syscall.h>
-
 #ifdef HAVE_LINUX_CAPABILITY_H
-#include <linux/capability.h>
+# include <linux/capability.h>
 #endif
-
 #ifdef HAVE_ASM_CACHECTL_H
-#include <asm/cachectl.h>
+# include <asm/cachectl.h>
 #endif
-
 #ifdef HAVE_LINUX_USTNAME_H
-#include <linux/utsname.h>
+# include <linux/utsname.h>
 #endif
-
 #ifdef HAVE_ASM_SYSMIPS_H
-#include <asm/sysmips.h>
+# include <asm/sysmips.h>
 #endif
-
 #include <linux/sysctl.h>
 
 static const struct xlat mount_flags[] = {
@@ -100,6 +92,7 @@ static const struct xlat mount_flags[] = {
        { MS_KERNMOUNT, "MS_KERNMOUNT"  },
        { MS_I_VERSION, "MS_I_VERSION"  },
        { MS_STRICTATIME,"MS_STRICTATIME"},
+       { MS_NOSEC,     "MS_NOSEC"      },
        { MS_BORN,      "MS_BORN"       },
        { MS_MANDLOCK,  "MS_MANDLOCK"   },
        { MS_NOATIME,   "MS_NOATIME"    },
@@ -214,6 +207,72 @@ sys_personality(struct tcb *tcp)
        return 0;
 }
 
+enum {
+       SYSLOG_ACTION_CLOSE = 0,
+       SYSLOG_ACTION_OPEN,
+       SYSLOG_ACTION_READ,
+       SYSLOG_ACTION_READ_ALL,
+       SYSLOG_ACTION_READ_CLEAR,
+       SYSLOG_ACTION_CLEAR,
+       SYSLOG_ACTION_CONSOLE_OFF,
+       SYSLOG_ACTION_CONSOLE_ON,
+       SYSLOG_ACTION_CONSOLE_LEVEL,
+       SYSLOG_ACTION_SIZE_UNREAD,
+       SYSLOG_ACTION_SIZE_BUFFER
+};
+
+static const struct xlat syslog_action_type[] = {
+       { SYSLOG_ACTION_CLOSE,          "SYSLOG_ACTION_CLOSE"           },
+       { SYSLOG_ACTION_OPEN,           "SYSLOG_ACTION_OPEN"            },
+       { SYSLOG_ACTION_READ,           "SYSLOG_ACTION_READ"            },
+       { SYSLOG_ACTION_READ_ALL,       "SYSLOG_ACTION_READ_ALL"        },
+       { SYSLOG_ACTION_READ_CLEAR,     "SYSLOG_ACTION_READ_CLEAR"      },
+       { SYSLOG_ACTION_CLEAR,          "SYSLOG_ACTION_CLEAR"           },
+       { SYSLOG_ACTION_CONSOLE_OFF,    "SYSLOG_ACTION_CONSOLE_OFF"     },
+       { SYSLOG_ACTION_CONSOLE_ON,     "SYSLOG_ACTION_CONSOLE_ON"      },
+       { SYSLOG_ACTION_CONSOLE_LEVEL,  "SYSLOG_ACTION_CONSOLE_LEVEL"   },
+       { SYSLOG_ACTION_SIZE_UNREAD,    "SYSLOG_ACTION_SIZE_UNREAD"     },
+       { SYSLOG_ACTION_SIZE_BUFFER,    "SYSLOG_ACTION_SIZE_BUFFER"     },
+       { 0,                            NULL                            }
+};
+
+int
+sys_syslog(struct tcb *tcp)
+{
+       int type = tcp->u_arg[0];
+
+       if (entering(tcp)) {
+               /* type */
+               printxval(syslog_action_type, type, "SYSLOG_ACTION_???");
+               tprints(", ");
+       }
+
+       switch (type) {
+               case SYSLOG_ACTION_READ:
+               case SYSLOG_ACTION_READ_ALL:
+               case SYSLOG_ACTION_READ_CLEAR:
+                       if (entering(tcp))
+                               return 0;
+                       break;
+               default:
+                       if (entering(tcp)) {
+                               tprintf("%#lx, %lu",
+                                       tcp->u_arg[1], tcp->u_arg[2]);
+                       }
+                       return 0;
+       }
+
+       /* bufp */
+       if (syserror(tcp))
+               tprintf("%#lx", tcp->u_arg[1]);
+       else
+               printstr(tcp, tcp->u_arg[1], tcp->u_rval);
+       /* len */
+       tprintf(", %d", (int) tcp->u_arg[2]);
+
+       return 0;
+}
+
 #include <linux/reboot.h>
 static const struct xlat bootflags1[] = {
        { LINUX_REBOOT_MAGIC1,  "LINUX_REBOOT_MAGIC1"   },
@@ -319,7 +378,7 @@ sys_sram_alloc(struct tcb *tcp)
                /* size */
                tprintf("%lu, ", tcp->u_arg[0]);
                /* flags */
-               printxval(sram_alloc_flags, tcp->u_arg[1], "???_SRAM");
+               printflags(sram_alloc_flags, tcp->u_arg[1], "???_SRAM");
        }
        return 1;
 }
@@ -429,45 +488,75 @@ static const struct xlat capabilities[] = {
        { 0,            NULL            },
 };
 
+#ifndef _LINUX_CAPABILITY_VERSION_1
+# define _LINUX_CAPABILITY_VERSION_1 0x19980330
+#endif
+#ifndef _LINUX_CAPABILITY_VERSION_2
+# define _LINUX_CAPABILITY_VERSION_2 0x20071026
+#endif
+#ifndef _LINUX_CAPABILITY_VERSION_3
+# define _LINUX_CAPABILITY_VERSION_3 0x20080522
+#endif
+
+static const struct xlat cap_version[] = {
+       { _LINUX_CAPABILITY_VERSION_1,  "_LINUX_CAPABILITY_VERSION_1"   },
+       { _LINUX_CAPABILITY_VERSION_2,  "_LINUX_CAPABILITY_VERSION_3"   },
+       { _LINUX_CAPABILITY_VERSION_3,  "_LINUX_CAPABILITY_VERSION_3"   },
+       { 0,                            NULL                            }
+};
+
+static void
+print_cap_header(struct tcb *tcp, unsigned long addr)
+{
+       union { cap_user_header_t p; long *a; char *c; } arg;
+       long a[sizeof(*arg.p) / sizeof(long) + 1];
+       arg.a = a;
+
+       if (!addr)
+               tprints("NULL");
+       else if (!verbose(tcp) ||
+                umoven(tcp, addr, sizeof(*arg.p), arg.c) < 0)
+               tprintf("%#lx", addr);
+       else {
+               tprints("{");
+               printxval(cap_version, arg.p->version,
+                         "_LINUX_CAPABILITY_VERSION_???");
+               tprintf(", %d}", arg.p->pid);
+       }
+}
+
+static void
+print_cap_data(struct tcb *tcp, unsigned long addr)
+{
+       union { cap_user_data_t p; long *a; char *c; } arg;
+       long a[sizeof(*arg.p) / sizeof(long) + 1];
+       arg.a = a;
+
+       if (!addr)
+               tprints("NULL");
+       else if (!verbose(tcp) ||
+                (exiting(tcp) && syserror(tcp)) ||
+                umoven(tcp, addr, sizeof(*arg.p), arg.c) < 0)
+               tprintf("%#lx", addr);
+       else {
+               tprints("{");
+               printflags(capabilities, arg.p->effective, "CAP_???");
+               tprints(", ");
+               printflags(capabilities, arg.p->permitted, "CAP_???");
+               tprints(", ");
+               printflags(capabilities, arg.p->inheritable, "CAP_???");
+               tprints("}");
+       }
+}
+
 int
 sys_capget(struct tcb *tcp)
 {
-       /* cap_user_ types are _pointers_ to (small) structs. */
-       /* Structs themselves have no names defined. */
-       /* Have to use ugly hack to place them on stack. */
-       cap_user_header_t arg0;
-       cap_user_data_t   arg1;
-       long a0[sizeof(*arg0) / sizeof(long) + 1];
-       long a1[sizeof(*arg1) / sizeof(long) + 1];
-       arg0 = (cap_user_header_t) a0;
-       arg1 = (cap_user_data_t  ) a1;
-
-       if (!entering(tcp)) {
-               if (!tcp->u_arg[0])
-                       tprints("NULL");
-               else if (!verbose(tcp))
-                       tprintf("%#lx", tcp->u_arg[0]);
-               else if (umoven(tcp, tcp->u_arg[0], sizeof(*arg0), (char *) arg0) < 0)
-                       tprints("???");
-               else {
-                       tprintf("%#x, %d", arg0->version, arg0->pid);
-               }
+       if (entering(tcp)) {
+               print_cap_header(tcp, tcp->u_arg[0]);
                tprints(", ");
-               if (!tcp->u_arg[1])
-                       tprints("NULL");
-               else if (!verbose(tcp))
-                       tprintf("%#lx", tcp->u_arg[1]);
-               else if (umoven(tcp, tcp->u_arg[1], sizeof(*arg1), (char *) arg1) < 0)
-                       tprints("???");
-               else {
-                       tprints("{");
-                       printflags(capabilities, arg1->effective, "CAP_???");
-                       tprints(", ");
-                       printflags(capabilities, arg1->permitted, "CAP_???");
-                       tprints(", ");
-                       printflags(capabilities, arg1->inheritable, "CAP_???");
-                       tprints("}");
-               }
+       } else {
+               print_cap_data(tcp, tcp->u_arg[1]);
        }
        return 0;
 }
@@ -475,39 +564,10 @@ sys_capget(struct tcb *tcp)
 int
 sys_capset(struct tcb *tcp)
 {
-       cap_user_header_t arg0;
-       cap_user_data_t   arg1;
-       long a0[sizeof(*arg0) / sizeof(long) + 1];
-       long a1[sizeof(*arg1) / sizeof(long) + 1];
-       arg0 = (cap_user_header_t) a0;
-       arg1 = (cap_user_data_t  ) a1;
-
        if (entering(tcp)) {
-               if (!tcp->u_arg[0])
-                       tprints("NULL");
-               else if (!verbose(tcp))
-                       tprintf("%#lx", tcp->u_arg[0]);
-               else if (umoven(tcp, tcp->u_arg[0], sizeof(*arg0), (char *) arg0) < 0)
-                       tprints("???");
-               else {
-                       tprintf("%#x, %d", arg0->version, arg0->pid);
-               }
+               print_cap_header(tcp, tcp->u_arg[0]);
                tprints(", ");
-               if (!tcp->u_arg[1])
-                       tprints("NULL");
-               else if (!verbose(tcp))
-                       tprintf("%#lx", tcp->u_arg[1]);
-               else if (umoven(tcp, tcp->u_arg[1], sizeof(*arg1), (char *) arg1) < 0)
-                       tprints("???");
-               else {
-                       tprints("{");
-                       printflags(capabilities, arg1->effective, "CAP_???");
-                       tprints(", ");
-                       printflags(capabilities, arg1->permitted, "CAP_???");
-                       tprints(", ");
-                       printflags(capabilities, arg1->inheritable, "CAP_???");
-                       tprints("}");
-               }
+               print_cap_data(tcp, tcp->u_arg[1]);
        }
        return 0;
 }
@@ -787,9 +847,9 @@ sys_sysctl(struct tcb *tcp)
            umoven(tcp, (unsigned long) info.name, size, (char *) name) < 0) {
                free(name);
                if (entering(tcp))
-                       tprintf("{%p, %d, %p, %p, %p, %Zu}",
+                       tprintf("{%p, %d, %p, %p, %p, %lu}",
                                info.name, info.nlen, info.oldval,
-                               info.oldlenp, info.newval, info.newlen);
+                               info.oldlenp, info.newval, (unsigned long)info.newlen);
                return 0;
        }
 
@@ -893,33 +953,33 @@ sys_sysctl(struct tcb *tcp)
                        tprints(", ...");
                tprintf("}, %d, ", info.nlen);
        } else {
-               size_t oldlen;
-               if (umove(tcp, (size_t)info.oldlenp, &oldlen) >= 0
-                   && info.nlen >= 2
-                   && ((name[0] == CTL_KERN
-                        && (name[1] == KERN_OSRELEASE
-                            || name[1] == KERN_OSTYPE
+               size_t oldlen = 0;
+               if (info.oldval == NULL) {
+                       tprints("NULL");
+               } else if (umove(tcp, (long)info.oldlenp, &oldlen) >= 0
+                          && info.nlen >= 2
+                          && ((name[0] == CTL_KERN
+                               && (name[1] == KERN_OSRELEASE
+                                   || name[1] == KERN_OSTYPE
 #ifdef KERN_JAVA_INTERPRETER
-                            || name[1] == KERN_JAVA_INTERPRETER
+                                   || name[1] == KERN_JAVA_INTERPRETER
 #endif
 #ifdef KERN_JAVA_APPLETVIEWER
-                            || name[1] == KERN_JAVA_APPLETVIEWER
+                                   || name[1] == KERN_JAVA_APPLETVIEWER
 #endif
-                                )))) {
+                                       )))) {
                        printpath(tcp, (size_t)info.oldval);
-                       tprintf(", %Zu, ", oldlen);
-                       if (info.newval == 0)
-                               tprints("NULL");
-                       else if (syserror(tcp))
-                               tprintf("%p", info.newval);
-                       else
-                               printpath(tcp, (size_t)info.newval);
-                       tprintf(", %Zd", info.newlen);
                } else {
-                       tprintf("%p, %Zd, %p, %Zd", info.oldval, oldlen,
-                               info.newval, info.newlen);
+                       tprintf("%p", info.oldval);
                }
-               tprints("}");
+               tprintf(", %lu, ", (unsigned long)oldlen);
+               if (info.newval == NULL)
+                       tprints("NULL");
+               else if (syserror(tcp))
+                       tprintf("%p", info.newval);
+               else
+                       printpath(tcp, (size_t)info.newval);
+               tprintf(", %lu", (unsigned long)info.newlen);
        }
 
        free(name);
@@ -966,3 +1026,63 @@ int sys_sysmips(struct tcb *tcp)
 }
 
 #endif /* MIPS */
+
+#ifdef OR1K
+#define OR1K_ATOMIC_SWAP        1
+#define OR1K_ATOMIC_CMPXCHG     2
+#define OR1K_ATOMIC_XCHG        3
+#define OR1K_ATOMIC_ADD         4
+#define OR1K_ATOMIC_DECPOS      5
+#define OR1K_ATOMIC_AND         6
+#define OR1K_ATOMIC_OR          7
+#define OR1K_ATOMIC_UMAX        8
+#define OR1K_ATOMIC_UMIN        9
+
+static const struct xlat atomic_ops[] = {
+       { OR1K_ATOMIC_SWAP,             "SWAP"          },
+       { OR1K_ATOMIC_CMPXCHG,          "CMPXCHG"       },
+       { OR1K_ATOMIC_XCHG,             "XCHG"          },
+       { OR1K_ATOMIC_ADD,              "ADD"           },
+       { OR1K_ATOMIC_DECPOS,           "DECPOS"        },
+       { OR1K_ATOMIC_AND,              "AND"           },
+       { OR1K_ATOMIC_OR,               "OR"            },
+       { OR1K_ATOMIC_UMAX,             "UMAX"          },
+       { OR1K_ATOMIC_UMIN,             "UMIN"          },
+       { 0, NULL }
+};
+
+int sys_or1k_atomic(struct tcb *tcp)
+{
+       if (entering(tcp)) {
+               printxval(atomic_ops, tcp->u_arg[0], "???");
+               switch(tcp->u_arg[0]) {
+               case OR1K_ATOMIC_SWAP:
+                       tprintf(", 0x%lx, 0x%lx", tcp->u_arg[1], tcp->u_arg[2]);
+                       break;
+               case OR1K_ATOMIC_CMPXCHG:
+                       tprintf(", 0x%lx, %#lx, %#lx", tcp->u_arg[1], tcp->u_arg[2],
+                               tcp->u_arg[3]);
+                       break;
+
+               case OR1K_ATOMIC_XCHG:
+               case OR1K_ATOMIC_ADD:
+               case OR1K_ATOMIC_AND:
+               case OR1K_ATOMIC_OR:
+               case OR1K_ATOMIC_UMAX:
+               case OR1K_ATOMIC_UMIN:
+                       tprintf(", 0x%lx, %#lx", tcp->u_arg[1], tcp->u_arg[2]);
+                       break;
+
+               case OR1K_ATOMIC_DECPOS:
+                       tprintf(", 0x%lx", tcp->u_arg[1]);
+                       break;
+
+               default:
+                       break;
+               }
+       }
+
+       return RVAL_HEX;
+}
+
+#endif /* OR1K */