2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6 * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
7 * Linux for s390 port by D.J. Barrow
8 * <barrow_dj@mail.yahoo.com,djbarrow@de.ibm.com>
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 #include <sys/param.h>
38 # include <sys/xattr.h>
46 string_to_uint(const char *str)
54 value = strtol(str, &error, 10);
55 if (errno || *error || value < 0 || (long)(int)value != value)
61 tv_nz(const struct timeval *a)
63 return a->tv_sec || a->tv_usec;
67 tv_cmp(const struct timeval *a, const struct timeval *b)
69 if (a->tv_sec < b->tv_sec
70 || (a->tv_sec == b->tv_sec && a->tv_usec < b->tv_usec))
72 if (a->tv_sec > b->tv_sec
73 || (a->tv_sec == b->tv_sec && a->tv_usec > b->tv_usec))
79 tv_float(const struct timeval *tv)
81 return tv->tv_sec + tv->tv_usec/1000000.0;
85 tv_add(struct timeval *tv, const struct timeval *a, const struct timeval *b)
87 tv->tv_sec = a->tv_sec + b->tv_sec;
88 tv->tv_usec = a->tv_usec + b->tv_usec;
89 if (tv->tv_usec >= 1000000) {
91 tv->tv_usec -= 1000000;
96 tv_sub(struct timeval *tv, const struct timeval *a, const struct timeval *b)
98 tv->tv_sec = a->tv_sec - b->tv_sec;
99 tv->tv_usec = a->tv_usec - b->tv_usec;
100 if (((long) tv->tv_usec) < 0) {
102 tv->tv_usec += 1000000;
107 tv_div(struct timeval *tv, const struct timeval *a, int n)
109 tv->tv_usec = (a->tv_sec % n * 1000000 + a->tv_usec + n / 2) / n;
110 tv->tv_sec = a->tv_sec / n + tv->tv_usec / 1000000;
111 tv->tv_usec %= 1000000;
115 tv_mul(struct timeval *tv, const struct timeval *a, int n)
117 tv->tv_usec = a->tv_usec * n;
118 tv->tv_sec = a->tv_sec * n + tv->tv_usec / 1000000;
119 tv->tv_usec %= 1000000;
123 xlookup(const struct xlat *xlat, const unsigned int val)
125 for (; xlat->str != NULL; xlat++)
126 if (xlat->val == val)
132 xlat_bsearch_compare(const void *a, const void *b)
134 const unsigned int val1 = (const unsigned long) a;
135 const unsigned int val2 = ((const struct xlat *) b)->val;
136 return (val1 > val2) ? 1 : (val1 < val2) ? -1 : 0;
140 xlat_search(const struct xlat *xlat, const size_t nmemb, const unsigned int val)
142 const struct xlat *e =
143 bsearch((const void*) (const unsigned long) val,
144 xlat, nmemb, sizeof(*xlat), xlat_bsearch_compare);
146 return e ? e->str : NULL;
149 #if !defined HAVE_STPCPY
151 stpcpy(char *dst, const char *src)
153 while ((*dst = *src++) != '\0')
159 /* Find a next bit which is set.
160 * Starts testing at cur_bit.
161 * Returns -1 if no more bits are set.
163 * We never touch bytes we don't need to.
164 * On big-endian, array is assumed to consist of
165 * current_wordsize wide words: for example, is current_wordsize is 4,
166 * the bytes are walked in 3,2,1,0, 7,6,5,4, 11,10,9,8 ... sequence.
167 * On little-endian machines, word size is immaterial.
170 next_set_bit(const void *bit_array, unsigned cur_bit, unsigned size_bits)
172 const unsigned endian = 1;
173 int little_endian = *(char*)&endian;
175 const uint8_t *array = bit_array;
176 unsigned pos = cur_bit / 8;
177 unsigned pos_xor_mask = little_endian ? 0 : current_wordsize-1;
183 if (cur_bit >= size_bits)
185 cur_byte = array[pos ^ pos_xor_mask];
187 cur_bit = (cur_bit + 8) & (-8);
191 bitmask = 1 << (cur_bit & 7);
193 if (cur_byte & bitmask)
196 if (cur_bit >= size_bits)
199 /* This check *can't be* optimized out: */
207 * Print entry in struct xlat table, if there.
210 printxval(const struct xlat *xlat, const unsigned int val, const char *dflt)
212 const char *str = xlookup(xlat, val);
217 tprintf("%#x /* %s */", val, dflt);
221 * Fetch 64bit argument at position arg_no and
222 * return the index of the next argument.
225 getllval(struct tcb *tcp, unsigned long long *val, int arg_no)
227 #if SIZEOF_LONG > 4 && SIZEOF_LONG == SIZEOF_LONG_LONG
228 # if SUPPORTED_PERSONALITIES > 1
229 if (current_wordsize > 4) {
231 *val = tcp->u_arg[arg_no];
233 # if SUPPORTED_PERSONALITIES > 1
235 # if defined(AARCH64) || defined(POWERPC64)
236 /* Align arg_no to the next even number. */
237 arg_no = (arg_no + 1) & 0xe;
238 # endif /* AARCH64 || POWERPC64 */
239 *val = LONG_LONG(tcp->u_arg[arg_no], tcp->u_arg[arg_no + 1]);
242 # endif /* SUPPORTED_PERSONALITIES > 1 */
243 #elif SIZEOF_LONG > 4
244 # error Unsupported configuration: SIZEOF_LONG > 4 && SIZEOF_LONG_LONG > SIZEOF_LONG
245 #elif defined LINUX_MIPSN32
246 *val = tcp->ext_arg[arg_no];
249 if (current_personality == 0) {
250 *val = tcp->ext_arg[arg_no];
253 *val = LONG_LONG(tcp->u_arg[arg_no], tcp->u_arg[arg_no + 1]);
257 # if defined __ARM_EABI__ || \
258 defined LINUX_MIPSO32 || \
261 /* Align arg_no to the next even number. */
262 arg_no = (arg_no + 1) & 0xe;
264 *val = LONG_LONG(tcp->u_arg[arg_no], tcp->u_arg[arg_no + 1]);
272 * Print 64bit argument at position arg_no and
273 * return the index of the next argument.
276 printllval(struct tcb *tcp, const char *format, int arg_no)
278 unsigned long long val = 0;
280 arg_no = getllval(tcp, &val, arg_no);
281 tprintf(format, val);
286 * Interpret `xlat' as an array of flags
287 * print the entries whose bits are on in `flags'
288 * return # of flags printed.
291 addflags(const struct xlat *xlat, int flags)
293 for (; xlat->str; xlat++) {
294 if (xlat->val && (flags & xlat->val) == xlat->val) {
295 tprintf("|%s", xlat->str);
300 tprintf("|%#x", flags);
305 * Interpret `xlat' as an array of flags.
306 * Print to static string the entries whose bits are on in `flags'
307 * Return static string.
310 sprintflags(const char *prefix, const struct xlat *xlat, int flags)
312 static char outstr[1024];
316 outptr = stpcpy(outstr, prefix);
318 for (; xlat->str; xlat++) {
319 if ((flags & xlat->val) == xlat->val) {
322 outptr = stpcpy(outptr, xlat->str);
332 outptr += sprintf(outptr, "%#x", flags);
339 printflags(const struct xlat *xlat, int flags, const char *dflt)
344 if (flags == 0 && xlat->val == 0) {
350 for (n = 0; xlat->str; xlat++) {
351 if (xlat->val && (flags & xlat->val) == xlat->val) {
352 tprintf("%s%s", sep, xlat->str);
361 tprintf("%s%#x", sep, flags);
366 tprintf("%#x", flags);
368 tprintf(" /* %s */", dflt);
379 printnum_long(struct tcb *tcp, long addr, const char *fmt)
387 if (umove(tcp, addr, &num) < 0) {
388 tprintf("%#lx", addr);
397 printnum_int(struct tcb *tcp, long addr, const char *fmt)
405 if (umove(tcp, addr, &num) < 0) {
406 tprintf("%#lx", addr);
418 static char buf[sizeof(int) * 3 * 6];
426 snprintf(buf, sizeof buf, "%02d/%02d/%02d-%02d:%02d:%02d",
427 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
428 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
430 snprintf(buf, sizeof buf, "%lu", (unsigned long) t);
436 getfdproto(struct tcb *tcp, int fd, char *buf, unsigned bufsize)
440 char path[sizeof("/proc/%u/fd/%u") + 2 * sizeof(int)*3];
445 sprintf(path, "/proc/%u/fd/%u", tcp->pid, fd);
446 r = getxattr(path, "system.sockprotoname", buf, bufsize - 1);
451 * This is a protection for the case when the kernel
452 * side does not append a null byte to the buffer.
463 printfd(struct tcb *tcp, int fd)
465 char path[PATH_MAX + 1];
466 if (show_fd_path && getfdpath(tcp, fd, path, sizeof(path)) >= 0) {
467 static const char socket_prefix[] = "socket:[";
468 const size_t socket_prefix_len = sizeof(socket_prefix) - 1;
469 const size_t path_len = strlen(path);
472 if (show_fd_path > 1 &&
473 strncmp(path, socket_prefix, socket_prefix_len) == 0 &&
474 path[path_len - 1] == ']') {
475 unsigned long inodenr;
476 #define PROTO_NAME_LEN 32
477 char proto_buf[PROTO_NAME_LEN];
479 getfdproto(tcp, fd, proto_buf, PROTO_NAME_LEN);
480 inodenr = strtoul(path + socket_prefix_len, NULL, 10);
481 if (!print_sockaddr_by_inode(inodenr, proto)) {
483 tprintf("%s:[%lu]", proto, inodenr);
488 print_quoted_string(path, path_len,
489 QUOTE_OMIT_LEADING_TRAILING_QUOTES);
497 * Quote string `instr' of length `size'
498 * Write up to (3 + `size' * 4) bytes to `outstr' buffer.
500 * If QUOTE_0_TERMINATED `style' flag is set,
501 * treat `instr' as a NUL-terminated string,
502 * checking up to (`size' + 1) bytes of `instr'.
504 * If QUOTE_OMIT_LEADING_TRAILING_QUOTES `style' flag is set,
505 * do not add leading and trailing quoting symbols.
507 * Returns 0 if QUOTE_0_TERMINATED is set and NUL was seen, 1 otherwise.
508 * Note that if QUOTE_0_TERMINATED is not set, always returns 1.
511 string_quote(const char *instr, char *outstr, const unsigned int size,
512 const unsigned int style)
514 const unsigned char *ustr = (const unsigned char *) instr;
519 if (style & QUOTE_0_TERMINATED)
522 eol = 0x100; /* this can never match a char */
528 /* Check for presence of symbol which require
529 to hex-quote the whole string. */
530 for (i = 0; i < size; ++i) {
532 /* Check for NUL-terminated string. */
536 /* Force hex unless c is printable or whitespace */
541 /* In ASCII isspace is only these chars: "\t\n\v\f\r".
542 * They happen to have ASCII codes 9,10,11,12,13.
544 if (c < ' ' && (unsigned)(c - 9) >= 5) {
551 if (!(style & QUOTE_OMIT_LEADING_TRAILING_QUOTES))
555 /* Hex-quote the whole string. */
556 for (i = 0; i < size; ++i) {
558 /* Check for NUL-terminated string. */
563 *s++ = "0123456789abcdef"[c >> 4];
564 *s++ = "0123456789abcdef"[c & 0xf];
567 for (i = 0; i < size; ++i) {
569 /* Check for NUL-terminated string. */
573 case '\"': case '\\':
598 if (c >= ' ' && c <= 0x7e)
604 && ustr[i + 1] >= '0'
605 && ustr[i + 1] <= '9'
608 *s++ = '0' + (c >> 6);
609 *s++ = '0' + ((c >> 3) & 0x7);
614 *s++ = '0' + (c >> 6);
615 *s++ = '0' + ((c >> 3) & 0x7);
618 *s++ = '0' + (c & 0x7);
625 if (!(style & QUOTE_OMIT_LEADING_TRAILING_QUOTES))
629 /* Return zero if we printed entire ASCIZ string (didn't truncate it) */
630 if (style & QUOTE_0_TERMINATED && ustr[i] == '\0') {
631 /* We didn't see NUL yet (otherwise we'd jump to 'asciz_ended')
632 * but next char is NUL.
640 if (!(style & QUOTE_OMIT_LEADING_TRAILING_QUOTES))
643 /* Return zero: we printed entire ASCIZ string (didn't truncate it) */
647 #ifndef ALLOCA_CUTOFF
648 # define ALLOCA_CUTOFF 4032
650 #define use_alloca(n) ((n) <= ALLOCA_CUTOFF)
653 * Quote string `str' of length `size' and print the result.
655 * If QUOTE_0_TERMINATED `style' flag is set,
656 * treat `str' as a NUL-terminated string and
657 * quote at most (`size' - 1) bytes.
659 * If QUOTE_OMIT_LEADING_TRAILING_QUOTES `style' flag is set,
660 * do not add leading and trailing quoting symbols.
662 * Returns 0 if QUOTE_0_TERMINATED is set and NUL was seen, 1 otherwise.
663 * Note that if QUOTE_0_TERMINATED is not set, always returns 1.
666 print_quoted_string(const char *str, unsigned int size,
667 const unsigned int style)
671 unsigned int alloc_size;
674 if (size && style & QUOTE_0_TERMINATED)
677 alloc_size = 4 * size;
678 if (alloc_size / 4 != size) {
679 error_msg("Out of memory");
683 alloc_size += 1 + (style & QUOTE_OMIT_LEADING_TRAILING_QUOTES ? 0 : 2);
685 if (use_alloca(alloc_size)) {
686 outstr = alloca(alloc_size);
689 outstr = buf = malloc(alloc_size);
691 error_msg("Out of memory");
697 rc = string_quote(str, outstr, size, style);
705 * Print path string specified by address `addr' and length `n'.
706 * If path length exceeds `n', append `...' to the output.
709 printpathn(struct tcb *tcp, long addr, unsigned int n)
711 char path[PATH_MAX + 1];
719 /* Cap path length to the path buffer size */
720 if (n > sizeof path - 1)
723 /* Fetch one byte more to find out whether path length > n. */
724 nul_seen = umovestr(tcp, addr, n + 1, path);
726 tprintf("%#lx", addr);
729 print_quoted_string(path, n, QUOTE_0_TERMINATED);
736 printpath(struct tcb *tcp, long addr)
738 /* Size must correspond to char path[] size in printpathn */
739 printpathn(tcp, addr, PATH_MAX);
743 * Print string specified by address `addr' and length `len'.
744 * If `len' < 0, treat the string as a NUL-terminated string.
745 * If string length exceeds `max_strlen', append `...' to the output.
748 printstr(struct tcb *tcp, long addr, long len)
750 static char *str = NULL;
760 /* Allocate static buffers if they are not allocated yet. */
762 unsigned int outstr_size = 4 * max_strlen + /*for quotes and NUL:*/ 3;
764 if (outstr_size / 4 != max_strlen)
766 str = xmalloc(max_strlen + 1);
767 outstr = xmalloc(outstr_size);
773 * Treat as a NUL-terminated string: fetch one byte more
774 * because string_quote may look one byte ahead.
776 if (umovestr(tcp, addr, size + 1, str) < 0) {
777 tprintf("%#lx", addr);
780 style = QUOTE_0_TERMINATED;
783 if (size > (unsigned long)len)
784 size = (unsigned long)len;
785 if (umoven(tcp, addr, size, str) < 0) {
786 tprintf("%#lx", addr);
792 /* If string_quote didn't see NUL and (it was supposed to be ASCIZ str
793 * or we were requested to print more than -s NUM chars)...
795 ellipsis = (string_quote(str, outstr, size, style) &&
796 (len < 0 || (unsigned long) len > max_strlen));
804 dumpiov(struct tcb *tcp, int len, long addr)
806 #if SUPPORTED_PERSONALITIES > 1
808 struct { u_int32_t base; u_int32_t len; } *iov32;
809 struct { u_int64_t base; u_int64_t len; } *iov64;
811 #define iov iovu.iov64
813 (current_wordsize == 4 ? sizeof(*iovu.iov32) : sizeof(*iovu.iov64))
814 #define iov_iov_base(i) \
815 (current_wordsize == 4 ? (uint64_t) iovu.iov32[i].base : iovu.iov64[i].base)
816 #define iov_iov_len(i) \
817 (current_wordsize == 4 ? (uint64_t) iovu.iov32[i].len : iovu.iov64[i].len)
820 #define sizeof_iov sizeof(*iov)
821 #define iov_iov_base(i) iov[i].iov_base
822 #define iov_iov_len(i) iov[i].iov_len
827 size = sizeof_iov * len;
828 /* Assuming no sane program has millions of iovs */
829 if ((unsigned)len > 1024*1024 /* insane or negative size? */
830 || (iov = malloc(size)) == NULL) {
831 error_msg("Out of memory");
834 if (umoven(tcp, addr, size, iov) >= 0) {
835 for (i = 0; i < len; i++) {
836 /* include the buffer number to make it easy to
837 * match up the trace with the source */
838 tprintf(" * %lu bytes in buffer %d\n",
839 (unsigned long)iov_iov_len(i), i);
840 dumpstr(tcp, (long) iov_iov_base(i),
852 dumpstr(struct tcb *tcp, long addr, int len)
854 static int strsize = -1;
855 static unsigned char *str;
860 "xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx "
861 "1234567890123456") + /*in case I'm off by few:*/ 4)
862 /*align to 8 to make memset easier:*/ + 7) & -8
864 const unsigned char *src;
867 memset(outbuf, ' ', sizeof(outbuf));
869 if (strsize < len + 16) {
871 str = malloc(len + 16);
874 error_msg("Out of memory");
880 if (umoven(tcp, addr, len, str) < 0)
883 /* Space-pad to 16 bytes */
895 *dst++ = "0123456789abcdef"[*src >> 4];
896 *dst++ = "0123456789abcdef"[*src & 0xf];
902 dst++; /* space is there by memset */
905 dst++; /* space is there by memset */
912 if (*src >= ' ' && *src < 0x7f)
919 tprintf(" | %05x %s |\n", i - 16, outbuf);
923 #ifdef HAVE_PROCESS_VM_READV
924 /* C library supports this, but the kernel might not. */
925 static bool process_vm_readv_not_supported = 0;
928 /* Need to do this since process_vm_readv() is not yet available in libc.
929 * When libc is be updated, only "static bool process_vm_readv_not_supported"
930 * line should remain.
932 #if !defined(__NR_process_vm_readv)
934 # define __NR_process_vm_readv 347
935 # elif defined(X86_64)
936 # define __NR_process_vm_readv 310
937 # elif defined(POWERPC)
938 # define __NR_process_vm_readv 351
942 #if defined(__NR_process_vm_readv)
943 static bool process_vm_readv_not_supported = 0;
944 /* Have to avoid duplicating with the C library headers. */
945 static ssize_t strace_process_vm_readv(pid_t pid,
946 const struct iovec *lvec,
947 unsigned long liovcnt,
948 const struct iovec *rvec,
949 unsigned long riovcnt,
952 return syscall(__NR_process_vm_readv, (long)pid, lvec, liovcnt, rvec, riovcnt, flags);
954 #define process_vm_readv strace_process_vm_readv
956 static bool process_vm_readv_not_supported = 1;
957 # define process_vm_readv(...) (errno = ENOSYS, -1)
960 #endif /* end of hack */
963 vm_read_mem(pid_t pid, void *laddr, long raddr, size_t len)
965 const struct iovec local = {
969 const struct iovec remote = {
970 .iov_base = (void *) raddr,
974 return process_vm_readv(pid, &local, 1, &remote, 1, 0);
978 * move `len' bytes of data from process `pid'
979 * at address `addr' to our space at `our_addr'
982 umoven(struct tcb *tcp, long addr, unsigned int len, void *our_addr)
984 char *laddr = our_addr;
986 unsigned int n, m, nread;
989 char x[sizeof(long)];
992 #if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
993 if (current_wordsize < sizeof(addr))
994 addr &= (1ul << 8 * current_wordsize) - 1;
997 if (!process_vm_readv_not_supported) {
998 int r = vm_read_mem(pid, laddr, addr, len);
999 if ((unsigned int) r == len)
1002 error_msg("umoven: short read (%u < %u) @0x%lx",
1003 (unsigned int) r, len, addr);
1008 process_vm_readv_not_supported = 1;
1011 /* operation not permitted, try PTRACE_PEEKDATA */
1014 /* the process is gone */
1016 case EFAULT: case EIO:
1017 /* address space is inaccessible */
1020 /* all the rest is strange and should be reported */
1021 perror_msg("process_vm_readv");
1027 if (addr & (sizeof(long) - 1)) {
1028 /* addr not a multiple of sizeof(long) */
1029 n = addr & (sizeof(long) - 1); /* residue */
1030 addr &= -sizeof(long); /* aligned address */
1032 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
1036 case ESRCH: case EINVAL:
1037 /* these could be seen if the process is gone */
1039 case EFAULT: case EIO: case EPERM:
1040 /* address space is inaccessible */
1043 /* all the rest is strange and should be reported */
1044 perror_msg("umoven: PTRACE_PEEKDATA pid:%d @0x%lx",
1048 m = MIN(sizeof(long) - n, len);
1049 memcpy(laddr, &u.x[n], m);
1050 addr += sizeof(long);
1057 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
1061 case ESRCH: case EINVAL:
1062 /* these could be seen if the process is gone */
1064 case EFAULT: case EIO: case EPERM:
1065 /* address space is inaccessible */
1067 perror_msg("umoven: short read (%u < %u) @0x%lx",
1068 nread, nread + len, addr - nread);
1072 /* all the rest is strange and should be reported */
1073 perror_msg("umoven: PTRACE_PEEKDATA pid:%d @0x%lx",
1077 m = MIN(sizeof(long), len);
1078 memcpy(laddr, u.x, m);
1079 addr += sizeof(long);
1089 * Like `umove' but make the additional effort of looking
1090 * for a terminating zero byte.
1092 * Returns < 0 on error, > 0 if NUL was seen,
1093 * (TODO if useful: return count of bytes including NUL),
1094 * else 0 if len bytes were read but no NUL byte seen.
1096 * Note: there is no guarantee we won't overwrite some bytes
1097 * in laddr[] _after_ terminating NUL (but, of course,
1098 * we never write past laddr[len-1]).
1101 umovestr(struct tcb *tcp, long addr, unsigned int len, char *laddr)
1103 #if SIZEOF_LONG == 4
1104 const unsigned long x01010101 = 0x01010101ul;
1105 const unsigned long x80808080 = 0x80808080ul;
1106 #elif SIZEOF_LONG == 8
1107 const unsigned long x01010101 = 0x0101010101010101ul;
1108 const unsigned long x80808080 = 0x8080808080808080ul;
1110 # error SIZEOF_LONG > 8
1114 unsigned int n, m, nread;
1117 char x[sizeof(long)];
1120 #if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
1121 if (current_wordsize < sizeof(addr))
1122 addr &= (1ul << 8 * current_wordsize) - 1;
1126 if (!process_vm_readv_not_supported) {
1127 const size_t page_size = get_pagesize();
1128 const size_t page_mask = page_size - 1;
1131 unsigned int chunk_len;
1132 unsigned int end_in_page;
1135 * Don't cross pages, otherwise we can get EFAULT
1136 * and fail to notice that terminating NUL lies
1137 * in the existing (first) page.
1139 chunk_len = len > page_size ? page_size : len;
1140 end_in_page = (addr + chunk_len) & page_mask;
1141 if (chunk_len > end_in_page) /* crosses to the next page */
1142 chunk_len -= end_in_page;
1144 int r = vm_read_mem(pid, laddr, addr, chunk_len);
1146 if (memchr(laddr, '\0', r))
1156 process_vm_readv_not_supported = 1;
1157 goto vm_readv_didnt_work;
1159 /* the process is gone */
1162 /* operation not permitted, try PTRACE_PEEKDATA */
1164 goto vm_readv_didnt_work;
1166 case EFAULT: case EIO:
1167 /* address space is inaccessible */
1169 perror_msg("umovestr: short read (%d < %d) @0x%lx",
1170 nread, nread + len, addr - nread);
1174 /* all the rest is strange and should be reported */
1175 perror_msg("process_vm_readv");
1181 vm_readv_didnt_work:
1183 if (addr & (sizeof(long) - 1)) {
1184 /* addr not a multiple of sizeof(long) */
1185 n = addr & (sizeof(long) - 1); /* residue */
1186 addr &= -sizeof(long); /* aligned address */
1188 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0);
1192 case ESRCH: case EINVAL:
1193 /* these could be seen if the process is gone */
1195 case EFAULT: case EIO: case EPERM:
1196 /* address space is inaccessible */
1199 /* all the rest is strange and should be reported */
1200 perror_msg("umovestr: PTRACE_PEEKDATA pid:%d @0x%lx",
1204 m = MIN(sizeof(long) - n, len);
1205 memcpy(laddr, &u.x[n], m);
1206 while (n & (sizeof(long) - 1))
1207 if (u.x[n++] == '\0')
1209 addr += sizeof(long);
1217 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0);
1221 case ESRCH: case EINVAL:
1222 /* these could be seen if the process is gone */
1224 case EFAULT: case EIO: case EPERM:
1225 /* address space is inaccessible */
1227 perror_msg("umovestr: short read (%d < %d) @0x%lx",
1228 nread, nread + len, addr - nread);
1232 /* all the rest is strange and should be reported */
1233 perror_msg("umovestr: PTRACE_PEEKDATA pid:%d @0x%lx",
1237 m = MIN(sizeof(long), len);
1238 memcpy(laddr, u.x, m);
1239 /* "If a NUL char exists in this word" */
1240 if ((u.val - x01010101) & ~u.val & x80808080)
1242 addr += sizeof(long);
1251 upeek(int pid, long off, long *res)
1256 val = ptrace(PTRACE_PEEKUSER, (pid_t)pid, (char *) off, 0);
1257 if (val == -1 && errno) {
1258 if (errno != ESRCH) {
1259 perror_msg("upeek: PTRACE_PEEKUSER pid:%d @0x%lx)", pid, off);