aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2020-06-02 14:44:08 +0200
committerMattias Andrée <maandree@kth.se>2020-06-02 14:44:08 +0200
commit7198c7b9f01bbd5e8f8528440d290569e588b260 (patch)
treec4bbeb956b37965d589ffe3c0b4dbde94e0ccaca
parentReject i386 and x32 applications (not yet supported) (diff)
downloadsctrace-7198c7b9f01bbd5e8f8528440d290569e588b260.tar.gz
sctrace-7198c7b9f01bbd5e8f8528440d290569e588b260.tar.bz2
sctrace-7198c7b9f01bbd5e8f8528440d290569e588b260.tar.xz
Some cleanup and preparation for support for multiple architectures (both host and client) and OSes
Signed-off-by: Mattias Andrée <maandree@kth.se>
-rw-r--r--Makefile9
-rw-r--r--arch-x86-64.h29
-rw-r--r--common.h38
-rw-r--r--config.mk5
-rw-r--r--consts.c2
-rw-r--r--linux/os.h32
-rw-r--r--linux/x86-64.h86
-rw-r--r--memory.c39
-rw-r--r--print.c120
-rw-r--r--sctrace.c29
10 files changed, 237 insertions, 152 deletions
diff --git a/Makefile b/Makefile
index 44c177b..9c02102 100644
--- a/Makefile
+++ b/Makefile
@@ -12,7 +12,8 @@ OBJ =\
util.o
HDR =\
- arch-x86-64.h\
+ linux/os.h\
+ linux/x86-64.h\
arg.h\
common.h\
list-errnos.h\
@@ -29,15 +30,13 @@ sctrace: $(OBJ)
list-errnos.h:
printf '#define LIST_ERRNOS(_)\\\n\t' > $@
- cat /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \
- | sed 's/\/\/.*$$//' | tr -d '$$' | sed 's/\*\//\$$/g' | sed 's/\/\*[^$$]*\$$//g' \
+ cat $(ERRNO_HDRS) sed 's/\/\/.*$$//' | tr -d '$$' | sed 's/\*\//\$$/g' | sed 's/\/\*[^$$]*\$$//g' \
| sed -n '/^[ \t]*#[ \t]*define[ \t].*[ \t][0-9]*[ \t]*$$/s/^[ \t#]*define[ \t]*\([^ \t]*\).*$$/_(\1)/p' \
| sort | uniq | tr '\n' '#' | sed 's/#_/\\\n\t_/g' | tr '#' '\n' >> $@
list-signums.h:
printf '#define LIST_SIGNUMS(_)\\\n\t' > $@
- cat /usr/include/bits/signum.h /usr/include/bits/signum-generic.h \
- | sed 's/\/\/.*$$//' | tr -d '$$' | sed 's/\*\//\$$/g' | sed 's/\/\*[^$$]*\$$//g' \
+ cat $(SIGNUM_HDRS) | sed 's/\/\/.*$$//' | tr -d '$$' | sed 's/\*\//\$$/g' | sed 's/\/\*[^$$]*\$$//g' \
| sed -n '/^[ \t]*#[ \t]*define[ \t][^_]*[ \t][0-9]*[ \t]*$$/s/^[ \t#]*define[ \t]*\([^ \t]*\).*$$/_(\1)/p' \
| sort | uniq | tr '\n' '#' | sed 's/#_/\\\n\t_/g' | tr '#' '\n' >> $@
diff --git a/arch-x86-64.h b/arch-x86-64.h
deleted file mode 100644
index 044b73f..0000000
--- a/arch-x86-64.h
+++ /dev/null
@@ -1,29 +0,0 @@
-struct i386_user_regs_struct
-{
- uint32_t ebx;
- uint32_t ecx;
- uint32_t edx;
- uint32_t esi;
- uint32_t edi;
- uint32_t ebp;
- uint32_t eax;
- uint32_t xds;
- uint32_t xes;
- uint32_t xfs;
- uint32_t xgs;
- uint32_t orig_eax;
- uint32_t eip;
- uint32_t xcs;
- uint32_t eflags;
- uint32_t esp;
- uint32_t xss;
-};
-
-#define SYSCALL_NUM_REG orig_rax
-#define SYSCALL_ARG1_REG rdi
-#define SYSCALL_ARG2_REG rsi
-#define SYSCALL_ARG3_REG rdx
-#define SYSCALL_ARG4_REG r10
-#define SYSCALL_ARG5_REG r8
-#define SYSCALL_ARG6_REG r9
-#define SYSCALL_RET_REG rax
diff --git a/common.h b/common.h
index 0c9ff8f..125611e 100644
--- a/common.h
+++ b/common.h
@@ -1,10 +1,5 @@
/* See LICENSE file for copyright and license details. */
-#include <linux/elf.h>
-#include <sys/ptrace.h>
-#include <linux/ptrace.h> /* After <sys/ptrace.h> */
-#include <sys/syscall.h>
#include <sys/uio.h>
-#include <sys/user.h>
#include <sys/wait.h>
#include <ctype.h>
#include <errno.h>
@@ -17,13 +12,9 @@
#include <string.h>
#include <unistd.h>
-#if defined(__x86_64__) && !defined(__IPL32__)
-# include "arch-x86-64.h"
+#if defined(__linux__)
+# include "linux/os.h"
#else
-# error "This program is only implemented for x86-64"
-#endif
-
-#if !defined(__linux__)
# error "This program is only implemented for Linux"
#endif
@@ -32,24 +23,6 @@
#include "list-signums.h"
-#ifndef ERESTARTSYS
-# define ERESTARTSYS 512
-# define ALSO_ERESTARTSYS
-#endif
-#ifndef ERESTARTNOINTR
-# define ERESTARTNOINTR 513
-# define ALSO_ERESTARTNOINTR
-#endif
-#ifndef ERESTARTNOHAND
-# define ERESTARTNOHAND 514
-# define ALSO_ERESTARTNOHAND
-#endif
-#ifndef ERESTART_RESTARTBLOCK
-# define ERESTART_RESTARTBLOCK 516
-# define ALSO_ERESTART_RESTARTBLOCK
-#endif
-
-
struct process;
enum type {
@@ -103,6 +76,11 @@ struct process {
unsigned long long int ret;
enum type ret_type;
struct output outputs[6];
+ /* multiarch support */
+ unsigned long long int scall_xor;
+ int long_is_int;
+ int ptr_is_int;
+ int mode;
/* vfork(2) data */
struct process *continue_on_exit;
@@ -119,6 +97,8 @@ char *get_string(pid_t pid, unsigned long int addr, size_t *lenp, const char **e
int get_struct(pid_t pid, unsigned long int addr, void *out, size_t size, const char **errorp);
char *get_memory(pid_t pid, unsigned long int addr, size_t n, const char **errorp);
char *escape_memory(char *str, size_t m);
+char *get_escaped_string(pid_t pid, unsigned long int addr, size_t *lenp, const char **errorp);
+char *get_escaped_memory(pid_t pid, unsigned long int addr, size_t n, const char **errorp);
/* print.c */
void print_systemcall(struct process *proc);
diff --git a/config.mk b/config.mk
index 9d233fb..8825261 100644
--- a/config.mk
+++ b/config.mk
@@ -1,6 +1,11 @@
PREFIX = /usr
MANPREFIX = $(PREFIX)/share/man
+CC = cc
+
+ERRNO_HDRS = /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h
+SIGNUM_HDRS = /usr/include/bits/signum.h /usr/include/bits/signum-generic.h
+
CPPFLAGS = -D_XOPEN_SOURCE=700 -D_GNU_SOURCE
CFLAGS = -std=c11 -Wall -Og -g
LDFLAGS =
diff --git a/consts.c b/consts.c
index 4e68230..8f6e4d9 100644
--- a/consts.c
+++ b/consts.c
@@ -9,6 +9,7 @@ get_errno_name(int err)
#define X(N) if (err == N) return #N;
LIST_ERRNOS(X)
+
#ifdef ALSO_ERESTARTSYS
X(ERESTARTSYS)
#endif
@@ -21,6 +22,7 @@ get_errno_name(int err)
#ifdef ALSO_ERESTART_RESTARTBLOCK
X(ERESTART_RESTARTBLOCK)
#endif
+
#undef X
sprintf(buf, "%i", err);
diff --git a/linux/os.h b/linux/os.h
new file mode 100644
index 0000000..db22f10
--- /dev/null
+++ b/linux/os.h
@@ -0,0 +1,32 @@
+/* See LICENSE file for copyright and license details. */
+#include <linux/elf.h>
+#include <sys/ptrace.h>
+#include <linux/ptrace.h> /* after <sys/ptrace.h> */
+#include <sys/syscall.h>
+#include <sys/user.h>
+
+#ifndef ERESTARTSYS
+# define ERESTARTSYS 512
+# define ALSO_ERESTARTSYS
+#endif
+#ifndef ERESTARTNOINTR
+# define ERESTARTNOINTR 513
+# define ALSO_ERESTARTNOINTR
+#endif
+#ifndef ERESTARTNOHAND
+# define ERESTARTNOHAND 514
+# define ALSO_ERESTARTNOHAND
+#endif
+#ifndef ERESTART_RESTARTBLOCK
+# define ERESTART_RESTARTBLOCK 516
+# define ALSO_ERESTART_RESTARTBLOCK
+#endif
+
+#define RETURN_IS_ERROR(RET)\
+ ((RET) > -(unsigned long long int)PAGE_SIZE) /* Don't know the actual limit, but this seems safe */
+
+#if defined(__x86_64__) && !defined(__IPL32__)
+# include "x86-64.h"
+#else
+# error "This program is only implemented for x86-64 on Linux"
+#endif
diff --git a/linux/x86-64.h b/linux/x86-64.h
new file mode 100644
index 0000000..16ff32f
--- /dev/null
+++ b/linux/x86-64.h
@@ -0,0 +1,86 @@
+/* See LICENSE file for copyright and license details. */
+struct i386_user_regs_struct
+{
+ uint32_t ebx;
+ uint32_t ecx;
+ uint32_t edx;
+ uint32_t esi;
+ uint32_t edi;
+ uint32_t ebp;
+ uint32_t eax;
+ uint32_t xds;
+ uint32_t xes;
+ uint32_t xfs;
+ uint32_t xgs;
+ uint32_t orig_eax;
+ uint32_t eip;
+ uint32_t xcs;
+ uint32_t eflags;
+ uint32_t esp;
+ uint32_t xss;
+};
+
+#define SYSCALL_NUM_REG orig_rax
+#define SYSCALL_RET_REG rax
+
+enum {
+ x86_64 = 0,
+ x32,
+ i386
+};
+
+#define CHECK_ARCHITECTURE(proc, regsp)\
+ do {\
+ struct iovec iov = {\
+ .iov_base = (regsp),\
+ .iov_len = sizeof(*(regsp)),\
+ };\
+ if (ptrace(PTRACE_GETREGSET, (proc)->pid, NT_PRSTATUS, &iov)) {\
+ eprintf("ptrace PTRACE_GETREGSET %ju NT_PRSTATUS {.iov_base=<buffer>, .iov_len=%zu}:",\
+ (uintmax_t)(proc)->pid, sizeof(*(regsp)));\
+ } else if (iov.iov_len != sizeof(*(regsp))) {\
+ if ((proc)->mode != i386) {\
+ (proc)->mode = i386;\
+ (proc)->long_is_int = 1;\
+ (proc)->ptr_is_int = 1;\
+ (proc)->scall_xor = 0;\
+ tprintf(proc, "Process is running in i386 mode, this is not yet supported\n"); /* TODO */\
+ exit(1);\
+ }\
+ } else if ((proc)->scall & __X32_SYSCALL_BIT) {\
+ if ((proc)->mode != x32) {\
+ (proc)->mode = x32;\
+ (proc)->long_is_int = 0;\
+ (proc)->ptr_is_int = 1;\
+ (proc)->scall_xor = __X32_SYSCALL_BIT;\
+ tprintf(proc, "Process is running in x32 mode (support is untested)\n");\
+ }\
+ } else {\
+ if ((proc)->mode != x86_64) {\
+ (proc)->mode = x86_64;\
+ (proc)->long_is_int = 0;\
+ (proc)->ptr_is_int = 0;\
+ (proc)->scall_xor = 0;\
+ tprintf(proc, "Process is running in x86-64 mode\n");\
+ }\
+ }\
+ } while (0)
+
+#define GET_SYSCALL_ARGUMENTS(proc, regsp)\
+ do {\
+ if ((proc)->mode != i386) {\
+ (proc)->args[0] = (regsp)->rdi;\
+ (proc)->args[1] = (regsp)->rsi;\
+ (proc)->args[2] = (regsp)->rdx;\
+ (proc)->args[3] = (regsp)->r10;\
+ (proc)->args[4] = (regsp)->r8;\
+ (proc)->args[5] = (regsp)->r9;\
+ } else {\
+ (proc)->args[0] = ((const struct i386_user_regs_struct *)(regsp))->ebx;\
+ (proc)->args[1] = ((const struct i386_user_regs_struct *)(regsp))->ecx;\
+ (proc)->args[2] = ((const struct i386_user_regs_struct *)(regsp))->edx;\
+ (proc)->args[3] = ((const struct i386_user_regs_struct *)(regsp))->esi;\
+ (proc)->args[4] = ((const struct i386_user_regs_struct *)(regsp))->edi;\
+ (proc)->args[5] = ((const struct i386_user_regs_struct *)(regsp))->ebp;\
+ }\
+ } while (0)
diff --git a/memory.c b/memory.c
index c721268..6262c61 100644
--- a/memory.c
+++ b/memory.c
@@ -5,6 +5,9 @@
char *
get_string(pid_t pid, unsigned long int addr, size_t *lenp, const char **errorp)
{
+#if defined(__x86_64__) && defined(__IPL32__)
+# error "x32 is not supported, would not be able to read memory from 64-bit applications with current method"
+#endif
struct iovec inv, outv;
size_t off = 0, size = 0, page_off, read_size;
char *out = NULL, *in = (char *)addr, *p;
@@ -39,14 +42,21 @@ int
get_struct(pid_t pid, unsigned long int addr, void *out, size_t size, const char **errorp)
{
struct iovec inv, outv;
+ if (!addr) {
+ *errorp = "NULL";
+ return -1;
+ }
*errorp = NULL;
+#if defined(__x86_64__) && defined(__IPL32__)
+# error "x32 is not supported, would not be able to read memory from 64-bit applications with current method"
+#endif
inv.iov_base = (void *)addr;
inv.iov_len = size;
outv.iov_base = out;
outv.iov_len = size;
if (process_vm_readv(pid, &outv, 1, &inv, 1, 0) == (ssize_t)size)
return 0;
- *errorp = errno == EFAULT ? "<invalid address>" : "<an error occured during reading of string>";
+ *errorp = errno == EFAULT ? "<invalid address>" : "<an error occured during reading of memory>";
return -1;
}
@@ -65,7 +75,6 @@ get_memory(pid_t pid, unsigned long int addr, size_t n, const char **errorp)
}
-
static void
add_char(char **strp, size_t *sizep, size_t *lenp, char c)
{
@@ -188,3 +197,29 @@ escape_memory(char *str, size_t m)
free(str);
return ret;
}
+
+
+char *
+get_escaped_string(pid_t pid, unsigned long int addr, size_t *lenp, const char **errorp)
+{
+ char *r;
+ if (!addr) {
+ *errorp = "NULL";
+ return NULL;
+ }
+ r = get_string(pid, addr, lenp, errorp);
+ return escape_memory(r, *lenp);
+}
+
+
+char *
+get_escaped_memory(pid_t pid, unsigned long int addr, size_t n, const char **errorp)
+{
+ char *r;
+ if (!addr) {
+ *errorp = "NULL";
+ return NULL;
+ }
+ r = get_memory(pid, addr, n, errorp);
+ return escape_memory(r, n);
+}
diff --git a/print.c b/print.c
index 8c572a8..ddd5a7c 100644
--- a/print.c
+++ b/print.c
@@ -13,48 +13,15 @@
#include <sched.h>
#include <time.h>
-#ifndef CLONE_NEWTIME
-# define CLONE_NEWTIME 0x00000080
+#if defined(__linux__)
+# ifndef CLONE_NEWTIME
+# define CLONE_NEWTIME 0x00000080
+# endif
#endif
-static char *
-get_escaped_string_or_null(pid_t pid, unsigned long int addr, size_t *lenp, const char **errorp)
-{
- char *r;
- if (!addr) {
- *errorp = "NULL";
- return NULL;
- }
- r = get_string(pid, addr, lenp, errorp);
- return escape_memory(r, *lenp);
-}
-
-static char *
-get_escaped_memory_or_null(pid_t pid, unsigned long int addr, size_t n, const char **errorp)
-{
- char *r;
- if (!addr) {
- *errorp = "NULL";
- return NULL;
- }
- r = get_memory(pid, addr, n, errorp);
- return escape_memory(r, n);
-}
-
-static int
-get_struct_or_null(pid_t pid, unsigned long int addr, void *out, size_t size, const char **errorp)
-{
- if (!addr) {
- *errorp = "NULL";
- return -1;
- }
- return get_struct(pid, addr, out, size, errorp);
-}
-
-
-
-#define CASE(N) if (proc->args[arg_index] == N) return tprintf(proc, "%s", #N)
+#define CASE(N)\
+ if (proc->args[arg_index] == N) return tprintf(proc, "%s", #N)
#define FLAGS_BEGIN\
do {\
@@ -146,7 +113,7 @@ print_timespec(struct process *proc, size_t arg_index)
{
struct timespec ts;
const char *err;
- if (get_struct_or_null(proc->pid, proc->args[arg_index], &ts, sizeof(ts), &err)) {
+ if (get_struct(proc->pid, proc->args[arg_index], &ts, sizeof(ts), &err)) {
tprintf(proc, "%s", err);
return;
}
@@ -270,7 +237,7 @@ print_int_pair(struct process *proc, size_t arg_index)
{
int pair[2];
const char *err;
- if (get_struct_or_null(proc->pid, proc->args[arg_index], pair, sizeof(pair), &err)) {
+ if (get_struct(proc->pid, proc->args[arg_index], pair, sizeof(pair), &err)) {
tprintf(proc, "%s", err);
return;
}
@@ -473,15 +440,26 @@ printf_systemcall(struct process *proc, const char *scall, const char *fmt, ...)
if (*fmt == 'p') {
p_fmt:
+ if (proc->ptr_is_int)
+ arg = (unsigned int)arg;
if (input) {
- if (get_struct_or_null(proc->pid, arg, &arg, sizeof(void *), &err)) {
- tprintf(proc, "%s", err);
- goto next;
+ if (proc->ptr_is_int) {
+ if (get_struct(proc->pid, arg, &arg, sizeof(int), &err)) {
+ tprintf(proc, "%s", err);
+ goto next;
+ }
+ arg = *(unsigned int *)&arg;
+ } else {
+ if (get_struct(proc->pid, arg, &arg, sizeof(long int), &err)) {
+ tprintf(proc, "%s", err);
+ goto next;
+ }
+ arg = *(unsigned long int *)&arg;
}
tprintf(proc, "&");
}
if (arg)
- tprintf(proc, "%p", (void *)arg);
+ tprintf(proc, "%#llu", arg);
else
tprintf(proc, "NULL");
} else if (*fmt >= '1' && *fmt <= '6') {
@@ -490,16 +468,16 @@ printf_systemcall(struct process *proc, const char *scall, const char *fmt, ...)
funcs[nfuncs++] = va_arg(ap, Function);
funcs[func - 1](proc, i);
} else if (*fmt == 's') {
- str = get_escaped_string_or_null(proc->pid, arg, &len, &err);
+ str = get_escaped_string(proc->pid, arg, &len, &err);
tprintf(proc, "%s", str ? str : err);
free(str);
} else if (*fmt == 'm') {
- str = get_escaped_memory_or_null(proc->pid, arg, (size_t)args[i + 1], &err);
+ str = get_escaped_memory(proc->pid, arg, (size_t)args[i + 1], &err);
tprintf(proc, "%s", str ? str : err);
free(str);
} else if (*fmt == 'F') {
if (input) {
- if (get_struct_or_null(proc->pid, arg, &arg, sizeof(int), &err)) {
+ if (get_struct(proc->pid, arg, &arg, sizeof(int), &err)) {
tprintf(proc, "%s", err);
goto next;
}
@@ -510,6 +488,8 @@ printf_systemcall(struct process *proc, const char *scall, const char *fmt, ...)
else
tprintf(proc, "%i", (int)arg);
} else {
+ if (ells == 1 && proc->long_is_int)
+ ells = 0;
if (ells == 1)
size = sizeof(long int);
else if (ells > 1)
@@ -521,7 +501,7 @@ printf_systemcall(struct process *proc, const char *scall, const char *fmt, ...)
else
size = sizeof(int);
if (input) {
- if (get_struct_or_null(proc->pid, arg, &arg, size, &err)) {
+ if (get_struct(proc->pid, arg, &arg, size, &err)) {
tprintf(proc, "%s", err);
goto next;
}
@@ -942,13 +922,13 @@ print_systemcall_exit(struct process *proc)
char *str, buf[32];
const char *err;
- if (proc->ret_type == Int)
+ if (proc->ret_type == Int || (proc->long_is_int && proc->ret_type == Long))
tprintf(proc, "= %i", (int)proc->ret);
- else if (proc->ret_type == UInt)
+ else if (proc->ret_type == UInt || (proc->long_is_int && proc->ret_type == ULong))
tprintf(proc, "= %u", (unsigned int)proc->ret);
- else if (proc->ret_type == OInt)
+ else if (proc->ret_type == OInt || (proc->long_is_int && proc->ret_type == OLong))
tprintf(proc, "= %#o", (unsigned int)proc->ret);
- else if (proc->ret_type == XInt)
+ else if (proc->ret_type == XInt || (proc->long_is_int && proc->ret_type == XLong))
tprintf(proc, "= %#x", (unsigned int)proc->ret);
else if (proc->ret_type == Long)
tprintf(proc, "= %li", (long int)proc->ret);
@@ -966,12 +946,14 @@ print_systemcall_exit(struct process *proc)
tprintf(proc, "= %#llo", (unsigned long long int)proc->ret);
else if (proc->ret_type == XLLong)
tprintf(proc, "= %#llx", (unsigned long long int)proc->ret);
+ else if (proc->ret_type == Ptr && (long long int)proc->ret >= 0 && proc->ptr_is_int)
+ tprintf(proc, "= %#u", (unsigned int)proc->ret);
else if (proc->ret_type == Ptr && (long long int)proc->ret >= 0)
- tprintf(proc, "= %p", (void *)proc->ret);
+ tprintf(proc, "= %#llu", proc->ret);
else
- tprintf(proc, "= %li", (long int)proc->ret);
+ tprintf(proc, "= %lli", (long long int)proc->ret);
- if ((unsigned long long int)proc->ret > -(unsigned long long int)PAGE_SIZE) {
+ if (RETURN_IS_ERROR(proc->ret)) {
tprintf(proc, " (%s: %s)", get_errno_name(-(int)proc->ret), strerror(-(int)proc->ret));
tprintf(proc, "\n");
@@ -984,17 +966,26 @@ print_systemcall_exit(struct process *proc)
switch (proc->outputs[i].fmt) {
case 'p':
- if (get_struct_or_null(proc->pid, proc->args[i], buf, sizeof(void *), &err))
- tprintf(proc, "%s\n", err);
- else if (*(void **)buf)
- tprintf(proc, "%p\n", *(void **)buf);
- else
- tprintf(proc, "NULL\n");
+ if (proc->ptr_is_int) {
+ if (get_struct(proc->pid, proc->args[i], buf, sizeof(int), &err))
+ tprintf(proc, "%s\n", err);
+ else if (*(unsigned int *)buf)
+ tprintf(proc, "%#u\n", *(unsigned int *)buf);
+ else
+ tprintf(proc, "NULL\n");
+ } else {
+ if (get_struct(proc->pid, proc->args[i], buf, sizeof(long int), &err))
+ tprintf(proc, "%s\n", err);
+ else if (*(unsigned long int *)buf)
+ tprintf(proc, "%#lu\n", *(unsigned long int *)buf);
+ else
+ tprintf(proc, "NULL\n");
+ }
break;
case 'm':
value = proc->args[i + 1] < proc->ret ? proc->args[i + 1] : proc->ret;
- str = get_escaped_memory_or_null(proc->pid, proc->args[i], (size_t)value, &err);
+ str = get_escaped_memory(proc->pid, proc->args[i], (size_t)value, &err);
tprintf(proc, "%s\n", str ? str : err);
free(str);
break;
@@ -1005,6 +996,7 @@ print_systemcall_exit(struct process *proc)
break;
default:
+ /* .ells is adjust for .long_is_int when set */
if (proc->outputs[i].ells == 1)
size = sizeof(unsigned long int);
else if (proc->outputs[i].ells > 1)
@@ -1015,7 +1007,7 @@ print_systemcall_exit(struct process *proc)
size = sizeof(unsigned char);
else
size = sizeof(unsigned int);
- if (get_struct_or_null(proc->pid, proc->args[i], buf, size, &err)) {
+ if (get_struct(proc->pid, proc->args[i], buf, size, &err)) {
tprintf(proc, "%s\n", err);
break;
}
diff --git a/sctrace.c b/sctrace.c
index 9bab8ff..3d2669a 100644
--- a/sctrace.c
+++ b/sctrace.c
@@ -18,10 +18,6 @@ static void
handle_syscall(struct process *proc)
{
struct user_regs_struct regs;
- struct iovec iov = {
- .iov_base = &regs,
- .iov_len = sizeof(regs),
- };
switch ((int)proc->state) {
default:
@@ -29,24 +25,11 @@ handle_syscall(struct process *proc)
if (ptrace(PTRACE_GETREGS, proc->pid, NULL, &regs))
eprintf("ptrace PTRACE_GETREGS %ju NULL <buffer>:", (uintmax_t)proc->pid);
proc->scall = regs.SYSCALL_NUM_REG;
- proc->args[0] = regs.SYSCALL_ARG1_REG;
- proc->args[1] = regs.SYSCALL_ARG2_REG;
- proc->args[2] = regs.SYSCALL_ARG3_REG;
- proc->args[3] = regs.SYSCALL_ARG4_REG;
- proc->args[4] = regs.SYSCALL_ARG5_REG;
- proc->args[5] = regs.SYSCALL_ARG6_REG;
-
- /* Check architecture */
- if (ptrace(PTRACE_GETREGSET, proc->pid, NT_PRSTATUS, &iov)) {
- eprintf("ptrace PTRACE_GETREGSET %ju NT_PRSTATUS {.iov_base=<buffer>, .iov_len=%zu}:",
- (uintmax_t)proc->pid, sizeof(regs));
- } else if (iov.iov_len != sizeof(regs)) {
- tprintf(proc, "Process is running as i386, this is not yet supported\n");
- exit(1);
- } else if (proc->scall & __X32_SYSCALL_BIT) {
- tprintf(proc, "Process is running as x32, this is not yet supported\n");
- exit(1);
- }
+#ifdef CHECK_ARCHITECTURE
+ CHECK_ARCHITECTURE(proc, &regs);
+ proc->scall ^= proc->scall_xor;
+#endif
+ GET_SYSCALL_ARGUMENTS(proc, &regs);
/* Print system call */
print_systemcall(proc);
@@ -115,7 +98,7 @@ handle_event(struct process *proc, int status)
struct process *proc2;
sig = WSTOPSIG(status);
- trace_event = ((status >> 8) ^ SIGTRAP) >> 8;
+ trace_event = status >> 16;
switch (trace_event) {
case PTRACE_EVENT_VFORK: