]> granicus.if.org Git - strace/blobdiff - util.c
Update AF_*, PF_*, MSG_*, and TCP_* constants
[strace] / util.c
diff --git a/util.c b/util.c
index 34c1b6260b4fcffb016507cc9d2de0ef9d7b05e0..6acdbc2946805629294e2c43586b12240ed670b3 100644 (file)
--- a/util.c
+++ b/util.c
 # undef pt_all_user_regs
 #endif
 
-/* macros */
-#ifndef MAX
-# define MAX(a,b)              (((a) > (b)) ? (a) : (b))
-#endif
-#ifndef MIN
-# define MIN(a,b)              (((a) < (b)) ? (a) : (b))
-#endif
-
 int
 string_to_uint(const char *str)
 {
@@ -185,39 +177,47 @@ printxval(const struct xlat *xlat, int val, const char *dflt)
 int
 printllval(struct tcb *tcp, const char *format, int arg_no)
 {
-#if defined(X86_64) || defined(POWERPC64) || defined(TILE)
-       if (current_personality == 0) {
-               /* Technically, format expects "long long",
-                * but we supply "long". We expect that
-                * on this arch, they are the same.
-                */
+#if SIZEOF_LONG > 4 && SIZEOF_LONG == SIZEOF_LONG_LONG
+# if SUPPORTED_PERSONALITIES > 1
+       if (current_wordsize > 4) {
+# endif
                tprintf(format, tcp->u_arg[arg_no]);
                arg_no++;
+# if SUPPORTED_PERSONALITIES > 1
        } else {
-# if defined(POWERPC64)
-               /* Align arg_no to next even number */
+#  if defined(AARCH64) || defined(POWERPC64)
+               /* Align arg_no to the next even number. */
                arg_no = (arg_no + 1) & 0xe;
-# endif
+#  endif
                tprintf(format, LONG_LONG(tcp->u_arg[arg_no], tcp->u_arg[arg_no + 1]));
                arg_no += 2;
        }
-#elif defined IA64 || defined ALPHA
-       /* Technically, format expects "long long",
-        * but we supply "long". We expect that
-        * on this arch, they are the same.
-        */
-       tprintf(format, tcp->u_arg[arg_no]);
-       arg_no++;
-#elif defined LINUX_MIPSN32 || defined X32
+# endif /* SUPPORTED_PERSONALITIES */
+#elif SIZEOF_LONG > 4
+#  error Unsupported configuration: SIZEOF_LONG > 4 && SIZEOF_LONG_LONG > SIZEOF_LONG
+#elif defined LINUX_MIPSN32
        tprintf(format, tcp->ext_arg[arg_no]);
        arg_no++;
+#elif defined X32
+       if (current_personality == 0) {
+               tprintf(format, tcp->ext_arg[arg_no]);
+               arg_no++;
+       } else {
+               tprintf(format, LONG_LONG(tcp->u_arg[arg_no], tcp->u_arg[arg_no + 1]));
+               arg_no += 2;
+       }
 #else
-# if SIZEOF_LONG > 4
-#  error BUG: must not combine two args for long long on this arch
+# if defined __ARM_EABI__ || \
+     defined LINUX_MIPSO32 || \
+     defined POWERPC || \
+     defined XTENSA
+       /* Align arg_no to the next even number. */
+       arg_no = (arg_no + 1) & 0xe;
 # endif
        tprintf(format, LONG_LONG(tcp->u_arg[arg_no], tcp->u_arg[arg_no + 1]));
        arg_no += 2;
 #endif
+
        return arg_no;
 }
 
@@ -353,10 +353,10 @@ printnum_int(struct tcb *tcp, long addr, const char *fmt)
 void
 printfd(struct tcb *tcp, int fd)
 {
-       const char *p;
+       char path[PATH_MAX + 1];
 
-       if (show_fd_path && (p = getfdpath(tcp, fd)))
-               tprintf("%d<%s>", fd, p);
+       if (show_fd_path && getfdpath(tcp, fd, path, sizeof(path)) >= 0)
+               tprintf("%d<%s>", fd, path);
        else
                tprintf("%d", fd);
 }
@@ -400,7 +400,16 @@ string_quote(const char *instr, char *outstr, long len, int size)
                        /* Check for NUL-terminated string. */
                        if (c == eol)
                                break;
-                       if (!isprint(c) && !isspace(c)) {
+
+                       /* Force hex unless c is printable or whitespace */
+                       if (c > 0x7e) {
+                               usehex = 1;
+                               break;
+                       }
+                       /* In ASCII isspace is only these chars: "\t\n\v\f\r".
+                        * They happen to have ASCII codes 9,10,11,12,13.
+                        */
+                       if (c < ' ' && (unsigned)(c - 9) >= 5) {
                                usehex = 1;
                                break;
                        }
@@ -453,7 +462,7 @@ string_quote(const char *instr, char *outstr, long len, int size)
                                        *s++ = 'v';
                                        break;
                                default:
-                                       if (isprint(c))
+                                       if (c >= ' ' && c <= 0x7e)
                                                *s++ = c;
                                        else {
                                                /* Print \octal */
@@ -843,7 +852,10 @@ umoven(struct tcb *tcp, long addr, int len, char *laddr)
                }
                m = MIN(sizeof(long) - n, len);
                memcpy(laddr, &u.x[n], m);
-               addr += sizeof(long), laddr += m, len -= m, nread += m;
+               addr += sizeof(long);
+               laddr += m;
+               nread += m;
+               len -= m;
        }
        while (len) {
                errno = 0;
@@ -869,7 +881,10 @@ umoven(struct tcb *tcp, long addr, int len, char *laddr)
                }
                m = MIN(sizeof(long), len);
                memcpy(laddr, u.x, m);
-               addr += sizeof(long), laddr += m, len -= m, nread += m;
+               addr += sizeof(long);
+               laddr += m;
+               nread += m;
+               len -= m;
        }
 
        return 0;
@@ -890,10 +905,20 @@ umoven(struct tcb *tcp, long addr, int len, char *laddr)
 int
 umovestr(struct tcb *tcp, long addr, int len, char *laddr)
 {
+#if SIZEOF_LONG == 4
+       const unsigned long x01010101 = 0x01010101ul;
+       const unsigned long x80808080 = 0x80808080ul;
+#elif SIZEOF_LONG == 8
+       const unsigned long x01010101 = 0x0101010101010101ul;
+       const unsigned long x80808080 = 0x8080808080808080ul;
+#else
+# error SIZEOF_LONG > 8
+#endif
+
        int pid = tcp->pid;
-       int i, n, m, nread;
+       int n, m, nread;
        union {
-               long val;
+               unsigned long val;
                char x[sizeof(long)];
        } u;
 
@@ -989,8 +1014,12 @@ umovestr(struct tcb *tcp, long addr, int len, char *laddr)
                while (n & (sizeof(long) - 1))
                        if (u.x[n++] == '\0')
                                return 1;
-               addr += sizeof(long), laddr += m, len -= m, nread += m;
+               addr += sizeof(long);
+               laddr += m;
+               nread += m;
+               len -= m;
        }
+
        while (len) {
                errno = 0;
                u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0);
@@ -1015,10 +1044,13 @@ umovestr(struct tcb *tcp, long addr, int len, char *laddr)
                }
                m = MIN(sizeof(long), len);
                memcpy(laddr, u.x, m);
-               for (i = 0; i < sizeof(long); i++)
-                       if (u.x[i] == '\0')
-                               return 1;
-               addr += sizeof(long), laddr += m, len -= m, nread += m;
+               /* "If a NUL char exists in this word" */
+               if ((u.val - x01010101) & ~u.val & x80808080)
+                       return 1;
+               addr += sizeof(long);
+               laddr += m;
+               nread += m;
+               len -= m;
        }
        return 0;
 }
@@ -1366,6 +1398,12 @@ change_syscall(struct tcb *tcp, arg_setup_state *state, int new)
        /* microblaze is only supported since about linux-2.6.30 */
 #elif defined(OR1K)
        /* never reached; OR1K is only supported by kernels since 3.1.0. */
+#elif defined(METAG)
+       /* setbpt/clearbpt never used: */
+       /* Meta is only supported since linux-3.7 */
+#elif defined(XTENSA)
+       /* setbpt/clearbpt never used: */
+       /* Xtensa is only supported since linux 2.6.13 */
 #else
 #warning Do not know how to handle change_syscall for this architecture
 #endif /* architecture */