# 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)
{
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;
}
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);
}
/* 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;
}
*s++ = 'v';
break;
default:
- if (isprint(c))
+ if (c >= ' ' && c <= 0x7e)
*s++ = c;
else {
/* Print \octal */
}
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;
}
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;
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;
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);
}
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;
}
/* 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 */