From: Denys Vlasenko Date: Fri, 1 Mar 2013 17:52:59 +0000 (+0100) Subject: umovestr: speed up check for NUL byte in the fetched word X-Git-Tag: v4.8~111 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1694092d7d92953dbee0639ead0ae379f145c4dd;p=strace umovestr: speed up check for NUL byte in the fetched word Signed-off-by: Denys Vlasenko --- diff --git a/util.c b/util.c index 34c1b626..00846a28 100644 --- a/util.c +++ b/util.c @@ -843,7 +843,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 +872,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 +896,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 +1005,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 +1035,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; }