void (*call)(const struct syscallname *,
abi_long, abi_long, abi_long,
abi_long, abi_long, abi_long);
- void (*result)(const struct syscallname *, abi_long);
+ void (*result)(const struct syscallname *, abi_long,
+ abi_long, abi_long, abi_long,
+ abi_long, abi_long, abi_long);
};
#ifdef __GNUC__
/* select */
#ifdef TARGET_NR__newselect
-static long newselect_arg1 = 0;
-static long newselect_arg2 = 0;
-static long newselect_arg3 = 0;
-static long newselect_arg4 = 0;
-static long newselect_arg5 = 0;
-
static void
print_newselect(const struct syscallname *name,
abi_long arg1, abi_long arg2, abi_long arg3,
abi_long arg4, abi_long arg5, abi_long arg6)
{
- qemu_log("%s(" TARGET_ABI_FMT_ld ",", name->name, arg1);
+ print_syscall_prologue(name);
print_fdset(arg1, arg2);
qemu_log(",");
print_fdset(arg1, arg3);
print_fdset(arg1, arg4);
qemu_log(",");
print_timeval(arg5, 1);
- qemu_log(")");
-
- /* save for use in the return output function below */
- newselect_arg1=arg1;
- newselect_arg2=arg2;
- newselect_arg3=arg3;
- newselect_arg4=arg4;
- newselect_arg5=arg5;
+ print_syscall_epilogue(name);
}
#endif
* Variants for the return value output function
*/
-static void
-print_syscall_ret_addr(const struct syscallname *name, abi_long ret)
+static bool
+print_syscall_err(abi_long ret)
{
- const char *errstr = NULL;
+ const char *errstr;
+ qemu_log(" = ");
if (ret < 0) {
errstr = target_strerror(-ret);
+ if (errstr) {
+ qemu_log("-1 errno=%d (%s)", (int)-ret, errstr);
+ return true;
+ }
}
- if (errstr) {
- qemu_log(" = -1 errno=%d (%s)\n", (int)-ret, errstr);
- } else {
- qemu_log(" = 0x" TARGET_ABI_FMT_lx "\n", ret);
+ return false;
+}
+
+static void
+print_syscall_ret_addr(const struct syscallname *name, abi_long ret,
+ abi_long arg0, abi_long arg1, abi_long arg2,
+ abi_long arg3, abi_long arg4, abi_long arg5)
+{
+ if (!print_syscall_err(ret)) {
+ qemu_log("0x" TARGET_ABI_FMT_lx, ret);
}
+ qemu_log("\n");
}
#if 0 /* currently unused */
#ifdef TARGET_NR__newselect
static void
-print_syscall_ret_newselect(const struct syscallname *name, abi_long ret)
-{
- qemu_log(" = 0x" TARGET_ABI_FMT_lx " (", ret);
- print_fdset(newselect_arg1,newselect_arg2);
- qemu_log(",");
- print_fdset(newselect_arg1,newselect_arg3);
- qemu_log(",");
- print_fdset(newselect_arg1,newselect_arg4);
- qemu_log(",");
- print_timeval(newselect_arg5, 1);
- qemu_log(")\n");
+print_syscall_ret_newselect(const struct syscallname *name, abi_long ret,
+ abi_long arg0, abi_long arg1, abi_long arg2,
+ abi_long arg3, abi_long arg4, abi_long arg5)
+{
+ if (!print_syscall_err(ret)) {
+ qemu_log(" = 0x" TARGET_ABI_FMT_lx " (", ret);
+ print_fdset(arg0, arg1);
+ qemu_log(",");
+ print_fdset(arg0, arg2);
+ qemu_log(",");
+ print_fdset(arg0, arg3);
+ qemu_log(",");
+ print_timeval(arg4, 1);
+ qemu_log(")");
+ }
+
+ qemu_log("\n");
}
#endif
#define TARGET_TIME_ERROR 5 /* clock not synchronized */
#ifdef TARGET_NR_adjtimex
static void
-print_syscall_ret_adjtimex(const struct syscallname *name, abi_long ret)
+print_syscall_ret_adjtimex(const struct syscallname *name, abi_long ret,
+ abi_long arg0, abi_long arg1, abi_long arg2,
+ abi_long arg3, abi_long arg4, abi_long arg5)
{
- const char *errstr = NULL;
-
- qemu_log(" = ");
- if (ret < 0) {
- qemu_log("-1 errno=%d", errno);
- errstr = target_strerror(-ret);
- if (errstr) {
- qemu_log(" (%s)", errstr);
- }
- } else {
+ if (!print_syscall_err(ret)) {
qemu_log(TARGET_ABI_FMT_ld, ret);
switch (ret) {
case TARGET_TIME_OK:
}
#endif
+#if defined(TARGET_NR_listxattr) || defined(TARGET_NR_llistxattr) \
+ || defined(TARGGET_NR_flistxattr)
+static void
+print_syscall_ret_listxattr(const struct syscallname *name, abi_long ret,
+ abi_long arg0, abi_long arg1, abi_long arg2,
+ abi_long arg3, abi_long arg4, abi_long arg5)
+{
+ if (!print_syscall_err(ret)) {
+ qemu_log(TARGET_ABI_FMT_ld, ret);
+ qemu_log(" (list = ");
+ if (arg1 != 0) {
+ abi_long attr = arg1;
+ while (ret) {
+ if (attr != arg1) {
+ qemu_log(",");
+ }
+ print_string(attr, 1);
+ ret -= target_strlen(attr) + 1;
+ attr += target_strlen(attr) + 1;
+ }
+ } else {
+ qemu_log("NULL");
+ }
+ qemu_log(")");
+ }
+
+ qemu_log("\n");
+}
+#define print_syscall_ret_llistxattr print_syscall_ret_listxattr
+#define print_syscall_ret_flistxattr print_syscall_ret_listxattr
+#endif
+
+#ifdef TARGET_NR_ioctl
+static void
+print_syscall_ret_ioctl(const struct syscallname *name, abi_long ret,
+ abi_long arg0, abi_long arg1, abi_long arg2,
+ abi_long arg3, abi_long arg4, abi_long arg5)
+{
+ if (!print_syscall_err(ret)) {
+ qemu_log(TARGET_ABI_FMT_ld, ret);
+
+ const IOCTLEntry *ie;
+ const argtype *arg_type;
+ void *argptr;
+ int target_size;
+
+ for (ie = ioctl_entries; ie->target_cmd != 0; ie++) {
+ if (ie->target_cmd == arg1) {
+ break;
+ }
+ }
+
+ if (ie->target_cmd == arg1 &&
+ (ie->access == IOC_R || ie->access == IOC_RW)) {
+ arg_type = ie->arg_type;
+ qemu_log(" (");
+ arg_type++;
+ target_size = thunk_type_size(arg_type, 0);
+ argptr = lock_user(VERIFY_READ, arg2, target_size, 1);
+ if (argptr) {
+ thunk_print(argptr, arg_type);
+ unlock_user(argptr, arg2, target_size);
+ } else {
+ print_pointer(arg2, 1);
+ }
+ qemu_log(")");
+ }
+ }
+ qemu_log("\n");
+}
+#endif
+
UNUSED static struct flags access_flags[] = {
FLAG_GENERIC(F_OK),
FLAG_GENERIC(R_OK),
FLAG_END,
};
+UNUSED static struct flags falloc_flags[] = {
+ FLAG_GENERIC(FALLOC_FL_KEEP_SIZE),
+ FLAG_GENERIC(FALLOC_FL_PUNCH_HOLE),
+#ifdef FALLOC_FL_NO_HIDE_STALE
+ FLAG_GENERIC(FALLOC_FL_NO_HIDE_STALE),
+#endif
+#ifdef FALLOC_FL_COLLAPSE_RANGE
+ FLAG_GENERIC(FALLOC_FL_COLLAPSE_RANGE),
+#endif
+#ifdef FALLOC_FL_ZERO_RANGE
+ FLAG_GENERIC(FALLOC_FL_ZERO_RANGE),
+#endif
+#ifdef FALLOC_FL_INSERT_RANGE
+ FLAG_GENERIC(FALLOC_FL_INSERT_RANGE),
+#endif
+#ifdef FALLOC_FL_UNSHARE_RANGE
+ FLAG_GENERIC(FALLOC_FL_UNSHARE_RANGE),
+#endif
+};
+
/*
* print_xxx utility functions. These are used to print syscall
* parameters in certain format. All of these have parameter
}
#endif
+#ifdef TARGET_NR_acct
+static void
+print_acct(const struct syscallname *name,
+ abi_long arg0, abi_long arg1, abi_long arg2,
+ abi_long arg3, abi_long arg4, abi_long arg5)
+{
+ print_syscall_prologue(name);
+ print_string(arg0, 1);
+ print_syscall_epilogue(name);
+}
+#endif
+
#ifdef TARGET_NR_brk
static void
print_brk(const struct syscallname *name,
}
#endif
+#if defined(TARGET_NR_chown) || defined(TARGET_NR_lchown)
+static void
+print_chown(const struct syscallname *name,
+ abi_long arg0, abi_long arg1, abi_long arg2,
+ abi_long arg3, abi_long arg4, abi_long arg5)
+{
+ print_syscall_prologue(name);
+ print_string(arg0, 0);
+ print_raw_param("%d", arg1, 0);
+ print_raw_param("%d", arg2, 1);
+ print_syscall_epilogue(name);
+}
+#define print_lchown print_chown
+#endif
+
#ifdef TARGET_NR_clock_adjtime
static void
print_clock_adjtime(const struct syscallname *name,
}
#endif
+#ifdef TARGET_NR_fallocate
+static void
+print_fallocate(const struct syscallname *name,
+ abi_long arg0, abi_long arg1, abi_long arg2,
+ abi_long arg3, abi_long arg4, abi_long arg5)
+{
+ print_syscall_prologue(name);
+ print_raw_param("%d", arg0, 0);
+ print_flags(falloc_flags, arg1, 0);
+#if TARGET_ABI_BITS == 32
+ print_raw_param("%" PRIu64, target_offset64(arg2, arg3), 0);
+ print_raw_param("%" PRIu64, target_offset64(arg4, arg5), 1);
+#else
+ print_raw_param(TARGET_ABI_FMT_ld, arg2, 0);
+ print_raw_param(TARGET_ABI_FMT_ld, arg3, 1);
+#endif
+ print_syscall_epilogue(name);
+}
+#endif
+
#ifdef TARGET_NR_fchmodat
static void
print_fchmodat(const struct syscallname *name,
#define print_fcntl64 print_fcntl
#endif
+#ifdef TARGET_NR_fgetxattr
+static void
+print_fgetxattr(const struct syscallname *name,
+ abi_long arg0, abi_long arg1, abi_long arg2,
+ abi_long arg3, abi_long arg4, abi_long arg5)
+{
+ print_syscall_prologue(name);
+ print_raw_param("%d", arg0, 0);
+ print_string(arg1, 0);
+ print_pointer(arg2, 0);
+ print_raw_param(TARGET_FMT_lu, arg3, 1);
+ print_syscall_epilogue(name);
+}
+#endif
+
+#ifdef TARGET_NR_flistxattr
+static void
+print_flistxattr(const struct syscallname *name,
+ abi_long arg0, abi_long arg1, abi_long arg2,
+ abi_long arg3, abi_long arg4, abi_long arg5)
+{
+ print_syscall_prologue(name);
+ print_raw_param("%d", arg0, 0);
+ print_pointer(arg1, 0);
+ print_raw_param(TARGET_FMT_lu, arg2, 1);
+ print_syscall_epilogue(name);
+}
+#endif
+
+#if defined(TARGET_NR_getxattr) || defined(TARGET_NR_lgetxattr)
+static void
+print_getxattr(const struct syscallname *name,
+ abi_long arg0, abi_long arg1, abi_long arg2,
+ abi_long arg3, abi_long arg4, abi_long arg5)
+{
+ print_syscall_prologue(name);
+ print_string(arg0, 0);
+ print_string(arg1, 0);
+ print_pointer(arg2, 0);
+ print_raw_param(TARGET_FMT_lu, arg3, 1);
+ print_syscall_epilogue(name);
+}
+#define print_lgetxattr print_getxattr
+#endif
+
+#if defined(TARGET_NR_listxattr) || defined(TARGET_NR_llistxattr)
+static void
+print_listxattr(const struct syscallname *name,
+ abi_long arg0, abi_long arg1, abi_long arg2,
+ abi_long arg3, abi_long arg4, abi_long arg5)
+{
+ print_syscall_prologue(name);
+ print_string(arg0, 0);
+ print_pointer(arg1, 0);
+ print_raw_param(TARGET_FMT_lu, arg2, 1);
+ print_syscall_epilogue(name);
+}
+#define print_llistxattr print_listxattr
+#endif
+
+#if defined(TARGET_NR_fremovexattr)
+static void
+print_fremovexattr(const struct syscallname *name,
+ abi_long arg0, abi_long arg1, abi_long arg2,
+ abi_long arg3, abi_long arg4, abi_long arg5)
+{
+ print_syscall_prologue(name);
+ print_raw_param("%d", arg0, 0);
+ print_string(arg1, 1);
+ print_syscall_epilogue(name);
+}
+#endif
+
+#if defined(TARGET_NR_removexattr) || defined(TARGET_NR_lremovexattr)
+static void
+print_removexattr(const struct syscallname *name,
+ abi_long arg0, abi_long arg1, abi_long arg2,
+ abi_long arg3, abi_long arg4, abi_long arg5)
+{
+ print_syscall_prologue(name);
+ print_string(arg0, 0);
+ print_string(arg1, 1);
+ print_syscall_epilogue(name);
+}
+#define print_lremovexattr print_removexattr
+#endif
#ifdef TARGET_NR_futimesat
static void
}
#endif
+#ifdef TARGET_NR_lseek
+static void
+print_lseek(const struct syscallname *name,
+ abi_long arg0, abi_long arg1, abi_long arg2,
+ abi_long arg3, abi_long arg4, abi_long arg5)
+{
+ print_syscall_prologue(name);
+ print_raw_param("%d", arg0, 0);
+ print_raw_param(TARGET_ABI_FMT_ld, arg1, 0);
+ switch (arg2) {
+ case SEEK_SET:
+ qemu_log("SEEK_SET"); break;
+ case SEEK_CUR:
+ qemu_log("SEEK_CUR"); break;
+ case SEEK_END:
+ qemu_log("SEEK_END"); break;
+#ifdef SEEK_DATA
+ case SEEK_DATA:
+ qemu_log("SEEK_DATA"); break;
+#endif
+#ifdef SEEK_HOLE
+ case SEEK_HOLE:
+ qemu_log("SEEK_HOLE"); break;
+#endif
+ default:
+ print_raw_param("%#x", arg2, 1);
+ }
+ print_syscall_epilogue(name);
+}
+#endif
+
#if defined(TARGET_NR_socket)
static void
print_socket(const struct syscallname *name,
}
#endif
+#ifdef TARGET_NR_ioctl
+static void
+print_ioctl(const struct syscallname *name,
+ abi_long arg0, abi_long arg1, abi_long arg2,
+ abi_long arg3, abi_long arg4, abi_long arg5)
+{
+ print_syscall_prologue(name);
+ print_raw_param("%d", arg0, 0);
+
+ const IOCTLEntry *ie;
+ const argtype *arg_type;
+ void *argptr;
+ int target_size;
+
+ for (ie = ioctl_entries; ie->target_cmd != 0; ie++) {
+ if (ie->target_cmd == arg1) {
+ break;
+ }
+ }
+
+ if (ie->target_cmd == 0) {
+ print_raw_param("%#x", arg1, 0);
+ print_raw_param("%#x", arg2, 1);
+ } else {
+ qemu_log("%s", ie->name);
+ arg_type = ie->arg_type;
+
+ if (arg_type[0] != TYPE_NULL) {
+ qemu_log(",");
+
+ switch (arg_type[0]) {
+ case TYPE_PTRVOID:
+ print_pointer(arg2, 1);
+ break;
+ case TYPE_CHAR:
+ case TYPE_SHORT:
+ case TYPE_INT:
+ print_raw_param("%d", arg2, 1);
+ break;
+ case TYPE_LONG:
+ print_raw_param(TARGET_ABI_FMT_ld, arg2, 1);
+ break;
+ case TYPE_ULONG:
+ print_raw_param(TARGET_ABI_FMT_lu, arg2, 1);
+ break;
+ case TYPE_PTR:
+ switch (ie->access) {
+ case IOC_R:
+ print_pointer(arg2, 1);
+ break;
+ case IOC_W:
+ case IOC_RW:
+ arg_type++;
+ target_size = thunk_type_size(arg_type, 0);
+ argptr = lock_user(VERIFY_READ, arg2, target_size, 1);
+ if (argptr) {
+ thunk_print(argptr, arg_type);
+ unlock_user(argptr, arg2, target_size);
+ } else {
+ print_pointer(arg2, 1);
+ }
+ break;
+ }
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ }
+ }
+ print_syscall_epilogue(name);
+}
+#endif
+
/*
* An array of all of the syscalls we know about
*/
void
-print_syscall_ret(int num, abi_long ret)
+print_syscall_ret(int num, abi_long ret,
+ abi_long arg1, abi_long arg2, abi_long arg3,
+ abi_long arg4, abi_long arg5, abi_long arg6)
{
int i;
- const char *errstr = NULL;
for(i=0;i<nsyscalls;i++)
if( scnames[i].nr == num ) {
if( scnames[i].result != NULL ) {
- scnames[i].result(&scnames[i], ret);
+ scnames[i].result(&scnames[i], ret,
+ arg1, arg2, arg3,
+ arg4, arg5, arg6);
} else {
- if (ret < 0) {
- errstr = target_strerror(-ret);
- }
- if (errstr) {
- qemu_log(" = -1 errno=" TARGET_ABI_FMT_ld " (%s)\n",
- -ret, errstr);
- } else {
- qemu_log(" = " TARGET_ABI_FMT_ld "\n", ret);
+ if (!print_syscall_err(ret)) {
+ qemu_log(TARGET_ABI_FMT_ld, ret);
}
+ qemu_log("\n");
}
break;
}